Spaces:
Running
Running
File size: 14,693 Bytes
159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 09bdca7 490ef4d 09bdca7 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d f58aa3c 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 28943c4 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a f58aa3c 11a4f8d f58aa3c 11a4f8d 09bdca7 490ef4d 17e3e51 490ef4d 11a4f8d f58aa3c 11a4f8d f58aa3c 11a4f8d f58aa3c 11a4f8d f58aa3c 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a d21f4c4 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a 11a4f8d 159d26a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | <!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>用 Pad 远程开发 · Tablet-Driven Remote Dev</title>
<style>
:root{
--bg:#fbfbfa; --fg:#1c1c1a; --muted:#6b6b66;
--line:#e4e3df; --card:#fff; --accent:#2f6f4f; --accent-soft:#eef4f0;
--mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
}
@media (prefers-color-scheme:dark){
:root{ --bg:#151614; --fg:#eceae4; --muted:#9b9a93;
--line:#2e302c; --card:#1d1f1c; --accent:#7fc39a; --accent-soft:#1f2a24; }
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);
font:16px/1.7 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
-webkit-font-smoothing:antialiased;}
.wrap{max-width:800px;margin:0 auto;padding:56px 24px 96px}
header h1{font-size:29px;line-height:1.3;margin:0 0 10px;letter-spacing:-.01em}
header p{margin:0;color:var(--muted);font-size:15px}
header .en{font-size:15px;color:var(--muted);font-weight:400;display:block;margin-top:4px}
nav{display:flex;gap:4px;margin:36px 0 40px;border-bottom:1px solid var(--line);overflow-x:auto}
nav button{appearance:none;background:none;border:0;border-bottom:2px solid transparent;
color:var(--muted);font:inherit;font-size:15px;padding:9px 14px;cursor:pointer;margin-bottom:-1px;white-space:nowrap}
nav button:hover{color:var(--fg)}
nav button[aria-selected="true"]{color:var(--fg);border-bottom-color:var(--accent);font-weight:600}
section[hidden]{display:none}
h2{font-size:13px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);
margin:44px 0 16px;font-weight:600}
h2:first-of-type{margin-top:0}
.lead{font-size:17px;margin:0 0 8px}
.lead-en{color:var(--muted);font-size:14px;margin:0 0 4px}
.flow{display:flex;flex-direction:column;gap:0;margin:8px 0 4px}
.node{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:14px 16px}
.node b{display:block;font-size:15px}
.node span{color:var(--muted);font-size:13.5px}
.node.hl{border-color:var(--accent);background:var(--accent-soft)}
.arrow{color:var(--muted);font-size:13px;padding:7px 0 7px 16px;display:flex;align-items:center;gap:9px}
.arrow::before{content:"↓";font-size:15px;color:var(--accent)}
.route-grid,.cards{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.route,.card{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:16px 18px}
.route h3,.card h3{margin:0 0 3px;font-size:15.5px}
.route p,.card p{margin:0;font-size:14px;color:var(--muted);line-height:1.65}
.route code{display:inline-block;margin-top:8px}
.card .en{display:block;color:var(--muted);font-size:12.5px;font-weight:400;margin-bottom:7px}
ol.steps{list-style:none;counter-reset:s;padding:0;margin:0}
ol.steps>li{counter-increment:s;position:relative;padding:0 0 26px 38px;border-left:1px solid var(--line);margin-left:11px}
ol.steps>li:last-child{border-left-color:transparent;padding-bottom:0}
ol.steps>li::before{content:counter(s);position:absolute;left:-11px;top:0;width:22px;height:22px;
border-radius:50%;background:var(--accent);color:#fff;font-size:12px;font-weight:700;
display:flex;align-items:center;justify-content:center}
@media (prefers-color-scheme:dark){ol.steps>li::before{color:#12140f}}
ol.steps h3{margin:0 0 3px;font-size:16px}
ol.steps p{margin:0 0 10px;color:var(--muted);font-size:14px}
pre{background:var(--card);border:1px solid var(--line);border-radius:8px;
padding:12px 14px;overflow-x:auto;margin:0;font:13px/1.65 var(--mono)}
pre .c{color:var(--muted)}
code{font:13.5px var(--mono);background:var(--accent-soft);padding:1px 5px;border-radius:4px}
table{width:100%;border-collapse:collapse;font-size:14px}
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);vertical-align:top}
th{font-size:12.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-weight:600}
td:first-child{white-space:nowrap;color:var(--muted)}
.note{border-left:2px solid var(--accent);padding:2px 0 2px 14px;color:var(--muted);font-size:14px;margin:16px 0}
.shot{margin:24px auto 30px;max-width:620px}
.shot img{display:block;width:100%;height:auto;border:1px solid var(--line);border-radius:12px;background:#000}
.shot video{display:block;width:100%;height:auto;border:1px solid var(--line);border-radius:12px;background:#000}
.shot.clip{max-width:420px}
.shot figcaption{margin-top:9px;color:var(--muted);font-size:13px;line-height:1.6;text-align:center}
.tag{display:inline-block;border:1px solid var(--line);border-radius:999px;padding:1px 8px;margin-right:5px;
color:var(--muted);font-size:12px;background:var(--card)}
footer{margin-top:64px;padding-top:20px;border-top:1px solid var(--line);color:var(--muted);font-size:13px}
@media (max-width:620px){
.route-grid,.cards{grid-template-columns:1fr}
.wrap{padding:36px 18px 72px}
header h1{font-size:24px}
nav button{padding-left:10px;padding-right:10px;font-size:14px}
}
</style>
</head>
<body>
<div class="wrap">
<header>
<h1>用一台 Pad,随时接管 Mac 与 GPU 集群
<span class="en">A real remote-development endpoint, built with Termux and bidirectional SSH</span>
</h1>
<p>近处走局域网,远处走腾讯云;需要公司网络时走 VPN。入口不变,路径自动选择。</p>
</header>
<nav role="tablist">
<button role="tab" aria-selected="true" data-t="connect">怎么连接 · Connect</button>
<button role="tab" aria-selected="false" data-t="termux">Termux 是什么</button>
<button role="tab" aria-selected="false" data-t="why">为什么这样做 · Why</button>
</nav>
<!-- ===================== CONNECT ===================== -->
<section id="connect">
<h2>现在的链路 · The new chain</h2>
<p class="lead">Pad 不再只是一个 SSH 客户端,而是一台能被双向访问的 Linux 终端。</p>
<p class="lead-en">Termux turns the tablet into an addressable Unix endpoint, not just a screen.</p>
<div class="flow">
<div class="node hl"><b>📱 OPPO Pad · Termux</b><span>zsh、SSH、会话切换和本地文件都在这里。</span></div>
<div class="arrow">同一局域网直接连接;在外面时经腾讯云中继</div>
<div class="node hl"><b>💻 Mac · 工作与 Agent 中心</b><span>Codex、git、项目文件和持久 tmux 会话运行在这里。</span></div>
<div class="arrow">Mac 已有的公司网络与 SSH 配置</div>
<div class="node"><b>🖥️ GPU 集群</b><span>NRT、Poly、Prenyx 等训练与推理环境。</span></div>
</div>
<div class="note">
Pad 开启 Sing-box 时可以直连集群;没有 VPN 时则自动借用 Mac 的网络。无论走哪条路,常用命令保持不变。
</div>
<h2>Pad 怎么连接 · From the Pad</h2>
<div class="route-grid">
<div class="route">
<h3>进入 Mac</h3>
<p>普通 Shell、恢复工作现场或直接启动 Codex。</p>
<code>MAC</code> <code>mac-cc</code> <code>CODEX</code>
</div>
<div class="route">
<h3>进入服务器</h3>
<p>SSH alias 已同步;VPN 可用就直连,否则经过 Mac。</p>
<code>NRT</code> <code>poly</code> <code>prenyx</code>
</div>
</div>
<h2>自动选路 · One name, two routes</h2>
<ol class="steps">
<li>
<h3>同一局域网:直连</h3>
<p>Pad 和 Mac 在同一个 Wi-Fi 时,SSH 直接在本地网络传输,延迟最低。</p>
</li>
<li>
<h3>人在外面:腾讯云中继</h3>
<p>Mac 和 Pad 都主动建立反向 SSH 隧道。云端端口只绑定到本机回环地址,不直接暴露给公网。</p>
</li>
<li>
<h3>入口始终不变</h3>
<p>连接命令先探测局域网,失败后自动切到腾讯云;不需要记 IP、端口或当前网络状态。</p>
</li>
</ol>
<h2>Mac 如何反向连接 Pad · Back to the Pad</h2>
<p class="lead">Mac 和运行在 Mac 上的 Agent 使用同一个入口。</p>
<p class="lead-en">The same alias works for a human shell, automation, and file transfer.</p>
<pre><span class="c"># 进入 Pad;局域网优先,腾讯云兜底</span>
ssh pad
<span class="c"># 在 Pad 执行一条独立命令</span>
ssh pad 'command'
<span class="c"># 双向传文件</span>
scp local-file pad:~/
scp pad:~/remote-file .</pre>
<div class="note">
这让 Agent 能直接检查 Pad 状态、读取最新截图、同步文件或打开测试页面。Pad 不再是链路末端,而是工作流的一部分。
</div>
<h2>只需要记住 · The essentials</h2>
<table>
<tr><th>入口</th><th>作用</th></tr>
<tr><td><code>mac-cc</code></td><td>从 Pad 回到 Mac 上名为 <code>cc</code> 的 tmux 工作现场</td></tr>
<tr><td><code>CODEX</code></td><td>在 Mac 上运行 Codex,Pad 只负责显示和输入</td></tr>
<tr><td><code>NRT</code> / <code>poly</code></td><td>连接 GPU 集群,自动选择直连或经 Mac</td></tr>
<tr><td><code>ssh pad</code></td><td>从 Mac 或 Agent 反向进入 Pad</td></tr>
</table>
</section>
<!-- ===================== TERMUX ===================== -->
<section id="termux" hidden>
<h2>一句话 · In one line</h2>
<p class="lead">Termux 在 Android 上提供一个真正的 Linux 命令行环境。</p>
<p class="lead-en">Termux turns the Pad into a Unix endpoint that can initiate and accept SSH connections.</p>
<figure class="shot">
<img src="assets/termux-pad.jpg" alt="OPPO Pad 上的 Termux 界面,正在显示 Mac 上的 Codex 会话" loading="lazy">
<figcaption>Pad 上的真实 Termux 界面。这里正在显示 Mac 上的 Codex 会话;Termux 负责终端、输入和连接,计算与 Agent 运行在 Mac 上。</figcaption>
</figure>
<figure class="shot clip">
<video controls playsinline preload="metadata" poster="assets/termux-pad.jpg" aria-label="在 OPPO Pad 上使用 Termux 连接 Mac、NRT 和 Codex 的完整操作录屏">
<source src="assets/termux-pad-workflow.mp4" type="video/mp4">
你的浏览器不支持视频播放,可以<a href="assets/termux-pad-workflow.mp4">下载录屏</a>查看。
</video>
<figcaption>3 分钟真实操作:从 Pad 里的 Termux 进入 NRT 与 Mac 上的 Codex,再切换到浏览器查看工作结果。全屏播放时终端文字更清楚。</figcaption>
</figure>
<div class="flow">
<div class="node hl"><b>📱 Pad 上的 Termux</b><span>运行 zsh、OpenSSH、命令别名和少量本地工具。</span></div>
<div class="arrow">输入 MAC、NRT、poly 或 prenyx</div>
<div class="node"><b>🔐 SSH 连接</b><span>负责把 Termux 这个本地终端接到另一台机器。</span></div>
<div class="arrow">连接成功后,命令在远端执行</div>
<div class="node hl"><b>🖥️ Mac 或 GPU 集群</b><span>真正运行 Codex、代码、训练和持久 tmux 会话。</span></div>
</div>
<div class="note">
刚打开 Termux 时,你仍然在 Pad 本地。只有执行连接命令之后,才会进入 Mac 或集群。
</div>
<h2>不要混淆 · Three different layers</h2>
<table>
<tr><th>工具</th><th>它负责什么</th></tr>
<tr><td><code>Termux</code></td><td>Pad 本地的 Linux 命令行环境</td></tr>
<tr><td><code>SSH</code></td><td>在 Pad、Mac、腾讯云和集群之间建立连接</td></tr>
<tr><td><code>tmux</code></td><td>让 Mac 或服务器上的会话在 SSH 断线后继续运行</td></tr>
</table>
</section>
<!-- ===================== WHY ===================== -->
<section id="why" hidden>
<p class="lead">一句话:把「拿在手里的设备」和「真正运行工作的机器」彻底解耦。</p>
<p class="lead-en">The tablet is the control surface; the Mac and clusters remain the computers.</p>
<h2>好处 · Advantages</h2>
<div class="cards">
<div class="card">
<h3>任何地方,同一个入口<span class="en">One command everywhere</span></h3>
<p>局域网和腾讯云自动切换,不再根据地点修改 Host、端口或跳板设置。</p>
</div>
<div class="card">
<h3>会话不会丢<span class="en">Sessions survive disconnects</span></h3>
<p>tmux 留在 Mac 上。锁屏、换 Wi-Fi 或隧道重连后,工作现场仍然完整。</p>
</div>
<div class="card">
<h3>集群有两条路<span class="en">Direct when possible</span></h3>
<p>Pad 有 Sing-box 时直连公司集群;否则让 Mac 继续承担公司网络入口。</p>
</div>
<div class="card">
<h3>Codex 打通所有设备<span class="en">One agent across every device</span></h3>
<p>Mac 上的 Codex 可以反向 SSH 控制 Pad,也能连接腾讯云和 GPU 集群;同一个 Agent 因此能在全部设备间执行命令、检查状态和传输文件。</p>
</div>
<div class="card">
<h3>Pad 不需要很强<span class="en">The device stops mattering</span></h3>
<p>编译、推理和 Agent 都在 Mac 或 GPU 集群运行,Pad 负责输入、显示与少量本地工具。</p>
</div>
<div class="card">
<h3>家里不暴露端口<span class="en">Nothing exposed at home</span></h3>
<p>Mac 和 Pad 都主动连向云端;家用路由器不需要公网 IP 或端口转发。</p>
</div>
</div>
<h2>边界 · What it is for</h2>
<table>
<tr><th>适合</th><th>不适合</th></tr>
<tr><td>CLI Agent、日志、Git、训练任务</td><td>需要大量拖拽或复杂 GUI 的工作</td></tr>
<tr><td>随时检查、修改和继续任务</td><td>把 Pad 当作本地高性能工作站</td></tr>
</table>
<div class="note">
它没有让计算更快,而是让「必须坐在电脑前」不再是前提。
<br>It makes nothing faster. It removes the requirement of being at your desk.
</div>
</section>
<footer>
<span class="tag">Termux</span><span class="tag">OpenSSH</span><span class="tag">tmux</span><span class="tag">reverse tunnel</span>
<br><br>地址、端口与用户名均为示意;密钥和认证信息不进入页面。
</footer>
</div>
<script>
const tabs = document.querySelectorAll('nav button');
tabs.forEach(button => button.addEventListener('click', () => {
tabs.forEach(item => item.setAttribute('aria-selected', String(item === button)));
document.querySelectorAll('section[id]').forEach(section => {
section.hidden = section.id !== button.dataset.t;
});
window.scrollTo({top:0, behavior:'smooth'});
}));
</script>
</body>
</html>
|