🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

手机遥控端 4uthen7/agent-remote

DeepSeek Harness
4uthen715 天前有提交已提供中文文档扫描:含敏感能力

在手机上实时查看编码智能体输出并一键批准提权

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add 4uthen7/agent-remote
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · ui
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/10/21·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 15 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

⚠︎ 实装验证未通过(unknown · 2026/10/21) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 65 处,展示前 55 条)
  • 写入本地文件
    agentd/src/config.ts:42
    mkdirSync(dir, { recursive: true, mode: 0o700 });
  • 读取密钥环境变量
    agentd/src/config.ts:46
    const fromEnv = process.env.AGENT_REMOTE_TOKEN?.trim();
  • 读取本地文件
    agentd/src/config.ts:50
    if (existsSync(tokenPath)) {
  • 读取本地文件
    agentd/src/config.ts:51
    const existing = readFileSync(tokenPath, "utf8").trim();
  • 写入本地文件
    agentd/src/config.ts:55
    writeFileSync(tokenPath, `${token}\n`, { mode: 0o600 });
  • 执行外部命令来自配置/变量
    agentd/src/config.ts:69
    const output = execFileSync(finder, [command], {
  • 读取本地文件
    agentd/src/config.ts:111
    if (existsSync(electron) && existsSync(asar)) {
  • 写入本地文件
    agentd/src/config.ts:135
    writeFileSync(patchPath, content, { mode: 0o600 });
  • 读取密钥环境变量
    agentd/src/config.ts:172
    const syncKey = process.env.AGENT_REMOTE_SYNC_KEY?.trim() || undefined;
  • 读取密钥环境变量
    agentd/src/config.ts:173
    const syncToken = process.env.AGENT_REMOTE_SYNC_TOKEN?.trim() || undefined;
  • 读取本地文件
    agentd/src/native-history.ts:41
    if (!existsSync(root)) return [];
  • 读取本地文件
    agentd/src/native-history.ts:47
    entries = readdirSync(dir, { withFileTypes: true });
  • 读取本地文件
    agentd/src/native-history.ts:62
    return { file, mtime: Math.round(statSync(file).mtimeMs), size: statSync(file).size };
  • 读取本地文件
    agentd/src/native-history.ts:85
    const lines = readFileSync(file, "utf8").split(/ ? /);
  • 读取本地文件
    agentd/src/native-history.ts:189
    const raw = readFileSync(file);
  • 读取本地文件
    agentd/src/native-history.ts:202
    if (!existsSync(root)) return [];
  • 写入本地文件
    agentd/src/session-store.ts:32
    mkdirSync(dir, { recursive: true, mode: 0o700 });
  • 读取本地文件
    agentd/src/session-store.ts:49
    if (!existsSync(this.dir)) return;
  • 读取本地文件
    agentd/src/session-store.ts:50
    for (const entry of readdirSync(this.dir)) {
  • 读取本地文件
    agentd/src/session-store.ts:53
    const raw = JSON.parse(readFileSync(path.join(this.dir, entry), "utf8")) as ArchivedSession;
  • 写入本地文件
    agentd/src/session-store.ts:190
    writeFileSync(temp, serialized, { mode: 0o600 });
  • 写入本地文件
    agentd/src/session-store.ts:192
    renameSync(temp, file);
  • 写入本地文件
    agentd/src/session-store.ts:195
    writeFileSync(file, serialized, { mode: 0o600 });
  • 删除本地文件
    agentd/src/session-store.ts:196
    rmSync(temp, { force: true });
  • 发起网络请求
    agentd/src/sync-client.ts:58
    const response = await fetch(this.endpoint(), {
  • 发起网络请求
    agentd/src/sync-client.ts:92
    const response = await fetch(this.endpoint(), {
  • 读取密钥环境变量
    agentd/src/sync-server.ts:10
    const token = process.env.AGENT_REMOTE_SYNC_TOKEN?.trim();
  • 写入本地文件
    agentd/src/sync-server.ts:18
    mkdirSync(storeDir, { recursive: true, mode: 0o700 });
  • 写入本地文件
    agentd/src/sync-server.ts:52
    writeFileSync(temp, data, { mode: 0o600 });
  • 写入本地文件
    agentd/src/sync-server.ts:54
    renameSync(temp, file);
  • 写入本地文件
    agentd/src/sync-server.ts:56
    writeFileSync(file, data, { mode: 0o600 });
  • 删除本地文件
    agentd/src/sync-server.ts:57
    rmSync(temp, { force: true });
  • 读取本地文件
    agentd/src/sync-server.ts:82
    if (!existsSync(file)) {
  • 读取本地文件
    agentd/src/sync-server.ts:88
    res.end(readFileSync(file, "utf8"));
  • 读取本地文件
    agentd/src/util.ts:37
    const stat = statSync(real);
  • 写入本地文件
    desktop/main.js:62
    fs.appendFileSync(path.join(dataHome || app.getPath("userData"), "agentd.log"), `${new Date().toISOString()} ${text}\n`);
  • 写入本地文件
    desktop/main.js:87
    fs.mkdirSync(sessionsDir, { recursive: true, mode: 0o700 });
  • 读取本地文件
    desktop/main.js:90
    if (fs.existsSync(oldSessions)) {
  • 读取本地文件
    desktop/main.js:94
    if (!fs.existsSync(tokenPath) && fs.existsSync(oldToken)) {
  • 写入本地文件
    desktop/main.js:95
    fs.copyFileSync(oldToken, tokenPath);
  • 写入本地文件
    desktop/main.js:96
    fs.chmodSync(tokenPath, 0o600);
  • 读取本地文件
    desktop/main.js:115
    settings = { ...defaults, ...JSON.parse(fs.readFileSync(settingsPath, "utf8")) };
  • 写入本地文件
    desktop/main.js:130
    fs.mkdirSync(path.dirname(settingsPath), { recursive: true, mode: 0o700 });
  • 写入本地文件
    desktop/main.js:131
    fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), { mode: 0o600 });
  • 读取本地文件
    desktop/main.js:138
    const existing = fs.readFileSync(tokenPath, "utf8").trim();
  • 执行外部命令来自配置/变量
    desktop/main.js:173
    const output = execFileSync(finder, [command], {
  • 读取本地文件
    desktop/main.js:194
    if (fs.existsSync(candidate)) return candidate;
  • 执行外部命令固定命令
    desktop/main.js:197
    return execFileSync("which", ["tailscale"], { encoding: "utf8" }).trim() || null;
  • 执行外部命令来自配置/变量
    desktop/main.js:210
    execFileSync(bin, ["status", "--json"], { encoding: "utf8", timeout: 4000 }),
  • 执行外部命令来自配置/变量
    desktop/main.js:214
    execFileSync(bin, ["serve", "--bg", `--https=${TAILSCALE_HTTPS_PORT}`, String(port)], {
  • 执行外部命令来自配置/变量
    desktop/main.js:228
    const proc = spawn(command, ["--version"], {
  • 执行外部命令来自配置/变量
    desktop/main.js:269
    execFileSync(bin, ["status", "--json"], { encoding: "utf8", timeout: 4000 }),
  • 读取本地文件
    desktop/main.js:358
    if (fs.existsSync(appPath)) {
  • 发起网络请求
    desktop/main.js:424
    const response = await fetch(`http://127.0.0.1:${port}/health`, {
  • 写入剪贴板
    desktop/main.js:611
    ipcMain.handle("host:copy", (_event, text) => { clipboard.writeText(String(text)); return true; });
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
Agent Remote 原生 iOS 和 Android 遥控端,用来操控跑在你自己 Mac 上的编码智能体。两个 App 都通过 token 鉴权的 WebSocket 与一个小巧的 Node 守护进程(agentd)配对,实时接收智能体输出,还能在手机上批准沙箱提权请求。 公开版本采用干净的原生 UI,界面标签为日文:iOS 用 SwiftUI,Android 用 Jetpack Compose。早先那套赛博/3D 视觉实验不在本仓库中。 在手机上使用(无需自行构建) 终端用户配置步骤见 docs/remote-access.md。 不需要连同一个 Wi-Fi:手机通过 Tailscale 访问主机。iOS 因 ATS 限制必须用 wss://。 桌面主机 App(无需 Node.js) 运行主机最省事的方式是用 Agent Remote Desktop,支持 Windows/macOS。它自带 Node、agentd 及其依赖,自动检测已安装的 DSH/Codex/Claude,启动服务并显示配对二维码。PC 上不用另外装 Node。 - 从 Releases 下载 AgentRemote-Setup-<version>.exe 或 Agent.Remote-<version>-arm64.dmg。
展开完整文档(README 剩余 1 节)
Agent Remote

原生 iOS 和 Android 遥控端,用来操控跑在你自己 Mac 上的编码智能体。两个 App 都通过 token 鉴权的 WebSocket 与一个小巧的 Node 守护进程(agentd)配对,实时接收智能体输出,还能在手机上批准沙箱提权请求。

公开版本采用干净的原生 UI,界面标签为日文:iOS 用 SwiftUI,Android 用 Jetpack Compose。早先那套赛博/3D 视觉实验不在本仓库中。

在手机上使用(无需自行构建)

终端用户配置步骤见 docs/remote-access.md。
不需要连同一个 Wi-Fi:手机通过 Tailscale 访问主机。iOS 因 ATS 限制必须用 wss://。

桌面主机 App(无需 Node.js)

运行主机最省事的方式是用 Agent Remote Desktop,支持 Windows/macOS。它自带 Node、agentd 及其依赖,自动检测已安装的 DSH/Codex/Claude,启动服务并显示配对二维码。PC 上不用另外装 Node。

- 从 Releases 下载 AgentRemote-Setup-<version>.exe 或 Agent.Remote-<version>-arm64.dmg。
- 构建产物未签名,Windows/macOS 可能弹警告;点 More info → Run anyway / 右键 → 打开 即可。
- 桌面 App 可操控 DSH、Codex 和 Claude Code。它还能检测 Cursor、VS Code、Windsurf、Aider、Gemini CLI 和 OpenCode 并列入清单,但这些工具暂时没有 agentd 适配器。
- 编码命令行工具不会静默安装或自动登录;请先按常规方式装好。App 本身不需要 Node/npm。

构建说明与限制:desktop/README.md。

| Sessions | Timeline |
| Sessions | Timeline |

| Connect | Approval |
| Connect | Approval |

| Android sessions | Android setup guide | Android approval |
| Android sessions | Android setup guide | Android approval |

| Android app lock | Android app-lock settings |
| Android app lock | Android app-lock settings |

功能

- 桌面端一键启动主机 — Windows .exe / macOS .dmg 内置 Node 和 agentd,启动时自动检测工具并显示二维码;手机应用保持不变。
- 三种运行时 — 在同一应用里按会话选择 DeepSeek Harness、OpenAI Codex 或 Claude Code。
- 会话控制 — 列出、创建、恢复和关闭会话。
- 实时输出 — 流式显示助手文本、思考过程、工具调用、命令输出和上下文用量。
- 一键审批 — 放行前先查看确切命令、工作目录、理由和 danger-full-access 提权,确认后仅允许一次。
- 模型切换 — 在会话界面切换所选运行时的模型。
- 原生客户端 — iOS 用 SwiftUI,Android 用 Jetpack Compose,支持分组列表、大标题、系统浅色/深色、日文标签,聊天布局不挡视线。
- 可调试 Android APK — 提供 debug 签名、可调试的 APK,方便 adb install 和检查,无需商店签名。
- 渐进式设置指南 — 左上角 ? 按钮讲解主机 URL、二维码配对和后续每一步;建议随连接/会话进度推进。
- 应用锁 — iOS 支持 Face ID / Touch ID / Optic ID,Android 支持指纹或人脸,另有应用专用密码兜底。启动时和从后台返回时锁定;在 Settings → App lock 中开启。
- 会话历史与恢复 — 对话在 agentd 重启后依然保留,在应用里按项目分组,已结束的会话可重新打开,时间线完整保留。
- 自动重连 — Tailscale/局域网连接断开时保留当前时间线,按退避策略重试并重新订阅,不会退回顶层界面。
- 伪云同步 — 使用云同步的归档文件夹,或运行内置的加密同步中继,从每台主机加入同一房间。应用显示项目及其会话,可恢复属于所连主机的会话。
- 应用图标 — 连接界面上的黑色终端标志,随应用打包。
- 安全配对 — 二维码或 URL + bearer token;token 存放在 iOS Keychain 或 Android Keystore 加密的偏好设置中。
- 局域网或 Tailscale — Mac 无需开放入站端口;把两台设备放进同一 tailnet 即可在局域网外使用。

架构

┌────────────────────┐ WebSocket (token) ┌────────────────────┐
│ iPhone / Android │◀───────────────────────────────▶│ agentd │
│ SwiftUI │ │ Node + TypeScript │
└────────────────────┘ └─────────┬──────────┘
│ normalized
┌──────────────────┼──────────────────┐
┌──────▼──────┐ ┌───────▼──────┐ ┌───────▼──────┐
│ dsh acp │ │ codex │ │ Claude Agent │
│ DeepSeek │ │ app-server │ │ SDK │
└─────────────┘ └──────────────┘ └──────────────┘

agentd 按需启动会话选定的运行时,让每个上游进程独立于任何单个客户端,并向应用暴露一套统一的协议。应用从不直接与运行时通信。

- DSH —— 基于 stdio 生成的 ACP 配置档。
- Codex —— codex app-server --listen stdio://,采用一次性审批。
- Claude —— @anthropic-ai/claude-agent-sdk,把 canUseTool 映射到同一张审批表。

消息流转与审批关联的细节见 docs/architecture.md。

任意主机,任意手机

主机守护进程不绑定 macOS,移动客户端也不绑定某一种主机系统。

| 主机 | iPhone | Android |
| macOS 13+ | ✅ | ✅ |
| Windows 10 1809+ / 11 | ✅ | ✅ |
| Linux | ✅ | ✅ |

同一套二维码、URL + token、审批和模型菜单在每种组合下都能用。支持矩阵见 docs/platforms.md,原生 Windows 配置(防火墙、dsh/Codex/Claude、WSL2 回退)见 docs/windows.md。Windows 支持由 CI 在 windows-latest 上验证,包含真实的 agentd 启动与健康检查冒烟测试。

环境要求

- macOS 13+、Windows 10 1809+ 或 Linux,且至少有一个可用运行时:
- 已安装并登录 DeepSeek Harness
- 已登录 Codex CLI(codex login status 显示 ChatGPT)
- 已登录 Claude Code(claude auth status)或配置 ANTHROPIC_API_KEY
- Node.js 22.19+(推荐 Node 24)
- 构建 iOS 应用需要 Xcode 26+ 和 XcodeGen
- iPhone 或 Android 8+ 设备,与主机处于同一局域网,或两者都在同一个 Tailscale tailnet 中
- 只有从源码构建 Android 应用时才需要 JDK 17 + Android SDK 35

在 macOS 上使用 DSH 0.2.1-rc.2、Codex CLI 0.144.6 和 Claude Code 2.1.216 测试通过。Windows 由 CI(windows-latest)覆盖类型检查和 agentd 启动;在 Windows 主机上创建某个运行时的会话前,先安装并登录该运行时的命令行。Claude 需要 Claude Code 登录或 API key;缺少认证时应用会给出明确报错。

会话历史与恢复

agentd 把每个会话的摘要、原生运行时 id、配置和时间线保存到 AGENT_REMOTE_SYNC_DIR。启动时它还会导入已有的原生历史:Codex 线程、Claude Code 记录和 DSH 轮次大纲。应用按工作目录(项目)对活跃会话和已保存会话分组。点开已保存的会话即可阅读其历史;再开 会恢复原生 DSH/Codex/Claude 会话,并接着同一条时间线继续。

本地导入是自动的。跨主机同步需要手动开启:配置中继,或指定一个共享归档文件夹。没有房间密钥时,应用不会把你的历史记录发到任何地方。

原生恢复要求连接的宿主机上存在运行时状态。如果归档是通过共享云文件夹从另一台主机同步过来的,应用会把历史记录显示为只读,并告诉你它属于哪台主机。把文件夹设为云同步目录(iCloud Drive、Dropbox、OneDrive 等),就能让它像轻量云同步一样工作: bash
AGENT_REMOTE_SYNC_DIR="$HOME/Library/Mobile Documents/com~apple~CloudDocs/AgentRemote" npm start

加密同步中继

仓库里还包含一个小型中继服务器。它只存 AES-256-GCM 密文;房间密钥永远不会到达服务器。
bash

One always-on host (or a VPS/reverse proxy target)

AGENT_REMOTE_SYNC_TOKEN="server-token" npm run sync-server

Every agentd that should share the room

export AGENT_REMOTE_SYNC_URL="https://sync.example.com"
export AGENT_REMOTE_SYNC_ROOM="my-team"
export AGENT_REMOTE_SYNC_KEY="a-long-private-room-key"
export AGENT_REMOTE_SYNC_TOKEN="server-token"
npm start

任何人从 GitHub 安装 Agent Remote 都会得到同样的功能。要看到同一份归档,必须使用相同的中继 URL、房间和密钥;这些不在公开仓库里。没有密钥,中继只能看到密文。属于另一台主机的会话在那里是只读的;要恢复,请连接到拥有它的主机。

归档包含提示词、工具输出和目录路径。请使用私有的加密云文件夹或私有中继,不要公开房间密钥。

版本

每个发行版对应一个 Git 标签和一个 GitHub Release;同一个发行版内,应用和守护进程的版本可以不同。版本矩阵见 CHANGELOG.md 和 docs/platforms.md。

快速开始

1. 运行 agentd

macOS/Linux: bash
cd agentd
npm install
npm start

Windows(PowerShell):完整安装步骤见 docs/windows.md。
powershell
cd agentd
npm ci
npm start

agentd 会打印一个 WebSocket URL、一个 bearer token 和一个配对二维码。让它保持运行。它使用:

- ~/.dsh 存放 DeepSeek Harness 登录信息
- ~/.codex 存放 Codex CLI 登录信息
- ~/.claude 存放 Claude Code 登录信息
- ~/.agent-remote 存放桥接 token 和生成的 ACP 补丁
- workspace-write 权限模式,这样升级请求仍能送到你的手机

2. 构建应用 bash
cd ios
xcodegen generate
open AgentRemote.xcodeproj

选择你的团队,必要时设置一个唯一的 bundle identifier,然后在 iPhone 上运行。侧载构建: bash
cd ..
./scripts/build-ipa.sh

build/ipa/AgentRemote.ipa

IPA 未签名;Sideloadly 或 AltStore 会用你的 Apple ID 签名。见 docs/install.md。

Android
从 release 下载 AgentRemote-android-debug.apk,或者自行构建: bash
cd android
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

这个 APK 是 debug 构建:可调试,用标准 Android debug key 签名。
安装后的包名是 dev.fouruthent.agentremote,与 iOS bundle ID 分开。

主机 URL 填什么?

用 agentd 打印的 WebSocket: 那一行:

| 场景 | 主机 URL |
| 手机和主机连同一个 Wi-Fi | ws://<host LAN IP>:8787/ws(例如 ws://192.168.1.10:8787/ws) |
| Tailscale | ws://<tailscale IP>:8787/ws |
| Android 模拟器 | ws://10.0.2.2:8787/ws |

手机上不要用 127.0.0.1/localhost。最省事的做法是扫 agentd 终端里的二维码——URL 和 token 一次填好。点 ? 按钮打开设置指南,指南会随你的进度变化:开始 → 二维码/主机 → token → 连接 → 会话 → 审批。

3. 配对

打开应用,点 QR コードをスキャン,扫 agentd 终端里的二维码。
也可以手动配对:

- URL:agentd 打印的局域网 URL,例如 ws://192.168.1.10:8787/ws
- Token:cat ~/.agent-remote/token

手机上不要用 127.0.0.1——那指向手机自己。
要在局域网外使用,把两台设备都接入 Tailscale,用 tailnet IP: bash
AGENT_REMOTE_PUBLIC_URL="ws://$(tailscale ip -4):8787/ws" npm start

4. 创建会话

点撰写按钮,选 DeepSeek Harness、Codex 或 Claude Code。
三者共用同一套时间线、模型菜单和审批面板。某个运行时没登录时,会话会显示该运行时的错误,而不是让 daemon 失败。

安全模型

- agentd 用 bearer token 认证每条 WebSocket 连接。
- token 存在 iOS Keychain(AfterFirstUnlockThisDeviceOnly)或 Android Keystore 加密的 preferences 里。
- 可选的应用锁只存加盐的 PBKDF2-HMAC-SHA256 密码哈希(120,000 次迭代):iOS 存 Keychain,Android 存应用私有 preferences。它只是 UI 层的一道门;WebSocket token 仍由 Keychain/Keystore 保护。
- 审批是一次性的,并且与发起请求的具体工具调用和命令一一对应。danger-full-access 会明确显示,绝不自动批准。
- daemon 默认绑定 0.0.0.0:8787,好让局域网里的手机连上。不要把这个端口暴露到公网;用 Tailscale 或带认证的 TLS 代理。
- 当前传输在局域网(或 Tailscale)上走 ws://。应用层 E2E 信封和中继已在路线图上。本地开发启用了 NSAllowsArbitraryLoads;大范围发布前要换成 wss://。
- agentd 以你的 macOS 用户权限运行。审批时要像审查终端命令一样仔细。

威胁模型和漏洞上报方式见 SECURITY.md。

隐私

- iOS 和 Android 应用不含任何分析、广告或第三方 SDK。
- 只连接你输入或扫描的 agentd URL,没有厂商后端。
- 提示词、文件和模型输出只在你的手机、Mac 与所选运行时配置的模型服务商之间流转——就是你已经在用的那个服务商。
- 配对 token 存放在 iOS Keychain / Android Keystore 和 Mac 上的 ~/.agent-remote/token;它们不属于本仓库,也不在发布的 IPA 里。

配置

| 变量 | 默认值 | 用途 |
| AGENT_REMOTE_PORT | 8787 | WebSocket/HTTP 端口 |
| AGENT_REMOTE_BIND | 0.0.0.0 | 绑定地址;放在代理后面时用 127.0.0.1 |
| AGENT_REMOTE_HOME | ~/.agent-remote | 存放 token 和生成的 ACP 补丁 |
| AGENT_REMOTE_SYNC_DIR | ~/.agent-remote/sessions | 持久化会话归档;指向云同步文件夹即可实现伪云同步 |
| AGENT_REMOTE_IMPORT_HISTORY | 1 | 启动时导入已有的 Codex/Claude/DSH 历史(0 关闭) |
| AGENT_REMOTE_SYNC_URL | 未设置 | 加密中继的基础 URL;设置后启用中继同步 |
| AGENT_REMOTE_SYNC_ROOM | default | 中继房间名(和团队共享这个值) |
| AGENT_REMOTE_SYNC_KEY | 未设置 | 房间加密密钥;设置中继 URL 时必填 |
| AGENT_REMOTE_SYNC_TOKEN | 未设置 | 中继服务器的 Bearer token |
| AGENT_REMOTE_TOKEN | 自动生成 | 固定的 Bearer token |
| AGENT_REMOTE_ROOTS | $HOME | 允许的工作目录(用 : 分隔) |
| AGENT_REMOTE_PUBLIC_URL | 局域网 URL | 写进配对二维码的 URL |
| DSH_HOME | ~/.dsh | DeepSeek Harness 主目录 |
| AGENT_REMOTE_DSH_PROFILE | acp | DSH 配置档名称 |
| DSH_PROVIDER | deepseek-account | DSH 服务商 |
| DSH_MODEL | deepseek-flash | 默认模型 |
| DSH_BIN / DSH_APP_PATH | 自动 | 覆盖 DSH 运行时 |
| CODEX_BIN | codex | Codex 命令行路径 |
| AGENT_REMOTE_CLAUDE_MODEL | sonnet | 默认 Claude 模型别名 |

故障排查

首次运行时最常见的问题,列在下面。详细步骤见 docs/install.md 和 docs/windows.md。

EADDRINUSE: address already in use 0.0.0.0:8787

已经有一个 agentd 在运行。新进程会在打印二维码之前退出。
找到旧进程并停掉它: bash lsof -nP -iTCP:8787 -sTCP:LISTEN kill <PID>

或者换个端口启动这个实例: bash
AGENT_REMOTE_PORT=8788 npm start

then use ws://<host IP>:8788/ws in the app

看不到二维码

二维码只在启动时打印一次,输出在前台终端,位置在 WebSocket: / Token: / 主机地址这几行之后、Keep this process running 之前。
它不会写进文件。

- 在普通终端里运行 npm start,不要用 > log &,也不要作为后台服务运行。
- 把终端窗口拉宽;窗口太窄会把方块字符折行,导致扫不出来。
- 往上滚动,找 Scan this with the Agent Remote iOS app:。
- 重启 agentd,让它重新打印。Android 也能扫同一个二维码,尽管标签上写的是 iOS。
- 如果二维码不方便,手动输入 URL 和 token。

手机连不上

- 用 ws://<host LAN IP>:8787/ws(或 Tailscale IP),不要在手机上用 127.0.0.1/localhost。
- 让手机和主机连同一个 Wi-Fi,或者都接入 Tailscale。
- Windows 上允许 Node.js 访问专用网络(或为 TCP 8787 添加防火墙规则)。
- 在手机浏览器里打开 http://<host IP>:8787/health 检查。
- 主机上的 Android 模拟器:ws://10.0.2.2:8787/ws。

未授权 / token 错误

重新复制 Token: 那一行,或运行 token 命令,然后重新连接: bash

macOS / Linux

cat ~/.agent-remote/token
powershell

Windows PowerShell

Get-Content $HOME\.agent-remote\token

扫一个新二维码,是同时替换 URL 和 token 最简单的办法。

运行时起不来

- DSH: 安装 DSH 命令行,把 dsh 放进 PATH 或设置 DSH_BIN,然后登录。
- Codex: 运行 codex login status;更新 Codex(Windows 的 app-server 支持是最近才有的)。
- Claude: 运行 claude auth status,或设置 ANTHROPIC_API_KEY。
- Android 设置指南(左上角的 ?)会说明当前步骤和下一步操作。

不要分享二维码或终端 token 的截图;它能授予主机的控制权。

开发

做 UI 时跑 mock 守护进程——它会提供示例会话、工具调用和一个待处理的审批,不用启动 DSH: bash
cd agentd
node test/mock-server.mjs

ws://127.0.0.1:8788/ws, token "demo"

用 AGENT_REMOTE_URL=ws://127.0.0.1:8788/ws 和 AGENT_REMOTE_TOKEN=demo 启动模拟器应用,或者在应用里输入这些值。

在 agentd 运行且 DSH 已登录的情况下,跑端到端冒烟测试: bash
cd agentd
node test/smoke.mjs

冒烟测试会创建会话、发送提示词、试用模型切换,并批准一条写入临时文件的命令。

状态与路线图

- [x] DSH ACP 适配器、流式输出、审批、模型切换、恢复
- [x] Codex app-server 适配器,支持命令审批
- [x] Claude Agent SDK 适配器,支持 canUseTool 审批
- [x] 运行时选择器(DSH / Codex / Claude)和各运行时的模型菜单
- [x] 原生 iOS 客户端、二维码配对、Keychain、支持 Tailscale 的传输
- [x] 原生 Android 客户端(Jetpack Compose)、二维码配对、Keystore、可调试 APK
- [x] 简洁的日文 UI、未签名 IPA 打包
- [x] 应用图标(黑色终端标记)
- [x] Windows 主机支持(原生 + WSL2 回退),覆盖所有主机/客户端组合
- [x] 跨平台 CI(Windows/macOS/Linux 上的 agentd、Android APK、iOS 模拟器构建)
- [x] Face ID / Touch ID / Optic ID、Android 生物识别、应用密码回退
- [x] 持久会话历史、项目分组、原生恢复、文件/中继云归档
- [ ] 应用级端到端 + 中继
- [ ] APNs 推送通知
- [ ] App Store 加固

仓库结构

agentd/ Node 守护进程(WebSocket + DSH / Codex / Claude;macOS/Windows/Linux) ios/ SwiftUI 应用(XcodeGen) AgentRemote/ 简洁 UI + 共享客户端 android/ Jetpack Compose 应用(Gradle) app/ 原生 Android 客户端 scripts/build-ipa.sh 未签名设备 IPA docs/ 安装、架构、平台、Windows、截图 CHANGELOG.md 版本历史

许可证

MIT — 见 LICENSE。
预览分享卡片长什么样 ↓4uthen7/agent-remote
分享 · DeepSeek Harness Hub
4uthen7/agent-remote

在手机上实时查看编码智能体输出并一键批准提权

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部