Spaces:
Running
Running
Download index.html from Lawrence-cj/mobile-remote-dev: direct link, hf CLI and curl.
- Browser
- Download file 14.7 kB
-
https://huggingface.co/spaces/Lawrence-cj/mobile-remote-dev/resolve/main/index.html
- Command line
-
hf download hf://spaces/Lawrence-cj/mobile-remote-dev/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Lawrence-cj/mobile-remote-dev/resolve/main/index.html
14.7 kB
| <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> | |