Feature: 远程设置
September 18, 2026 · View on GitHub
| Field | Value |
|---|---|
| id | remote-settings |
| status | active |
| last verified | 2026-09-18 — 装机「开启远程→未响应」修复:主进程 loadServerApi 窄化为 pairing-offer.js + relay-device-credential-store.js(原 barrel ~3 万模块同步加载冻结主线程);DSH_VENDOR_PACKAGES 改镜像 + parity 测试。dshd-remote 36 pass、dshd-daemon-runner/remote-epipe/stdio-guard/lan/ipc 80 pass、ui-settings-remote 45/45、check:governance 6/6、npm run pack(80.7MiB runtime、sqlite ABI probe、daemon probe、skip compose)、打包布局窄入口 import+铸码 68ms、真实 Electron qa:remote 双冷启动 11/11(含 cold.openShowsQr)。此前:2026-09-11 — rc.1 后 dsh-im 各 channel 的 caller-scoped webServer 注入已修复;dsh-im check 19 pass / 1 skip、官方 remote specs、真实 source smoke 与 package dry-run 通过。再前:2026-09-08 — 默认服务器切到 ayase.cn:443 + TLS,公网 SPA 切到 https://ayase.cn/dshd/;旧内置 IP 精确迁移、自定义服务器保留。VPS relay 容器 healthy / 0 restart,nginx live 与候选配置通过;Node 远程聚焦 92 pass / 0 fail / 1 环境 skip,设置 UI 10/10,公网目录一致性通过,真实 daemon + 公网 relay + 公网 SPA E2E 10/10。未执行真机相机、Android WebView 或正式安装包升级验收。 |
User paths
当前可用: REMOTE_FEATURE_ENABLED=true;远程是否开启仍由用户控制。
- 设置 → 「远程」(
remote)→ 网关:选 局域网 / 服务器(文案区分;扫码传输都经中继);中继主机默认内置ayase.cn:443,使用 TLS。无宿主令牌墙。 - 设置 → 「远程」→ 消息渠道:桌面内置
@xmanrui/dsh-im完整 IM UI(九渠 + AI Office);无商店品牌头。 - 侧栏底部手机图标打开配对弹窗:开关 → 中继状态;中继已连接才显示扫码二维码 / 复制链接 / 刷新配对码 → 已配对设备 / 重命名 / 解除配对。
Invariants
-
全部 IM 渠道访问同进程本机 Harness 时通过
harness-auth-transport.mjs复用connection.authenticatedUrl/authorizeIndex换取 Cookie,覆盖 HTTP 与事件 WebSocket;不读取签名密钥、不取消鉴权、不向自定义外部地址或重定向发送本机凭据。旧版无认证 API 保持原行为。 -
检测到
typertGateway.wireStream时使用harness-modern-transport.mjs:旧点式 RPC 映射到当前 Remote API;健康检查取$eventsready,工作区/历史取真实 baseline/snapshot;prompt 的requestId保持原 RPC 归属;审批/问答经$events/result回传,停止不能越过原 IM 会话的所有权。不得只让健康检查变绿、继续调用已移除的接口。飞书 SDK 补丁先归一 CRLF,仍逐个严格检查源码片段。 -
连接方式文案为「局域网 / 服务器」;未设置时默认服务器(内部值
relay),局域网仅在明确选择lan时使用。既有显式选择保留,不自动开启远程。 -
新安装与空配置使用
ayase.cn:443+ TLS。升级时,只有精确匹配旧内置中继125.124.85.212:8411的保存值迁移到新默认;其他自定义中继地址及其 TLS 选择保持不变。旧内置公网页 overridehttp://125.124.85.212:3389/dshd清回默认解析,使二维码落到新公网页。 -
停放开关:
src/main/config.jsREMOTE_FEATURE_ENABLED。false 时 preload 不暴露getRemote/saveRemote/rotateRemoteToken/unbindRemoteDevice/renameRemoteDevice,ui-settings-remote不注册侧栏与设置入口;normalizeRemoteConfig把remoteEnabled钉死为 false;IPCshell:save-remote无法打开。解禁只翻这一处(window argv--dshd-remote-feature跟它走)。 -
配对协议 = dshd offer(实现为 vendored ChisaCode offer v2):全量
createChisaCodeDaemon跑在dshd-daemon-runner.mjs子进程(禁止回迁主进程);主进程DshdRemote只是进程管理面 + file-backed 配对/快照;QRappBaseUrl:局域网 =preferredLanIp():3180,服务器 =DEFAULT_PUBLIC_APP_BASE_URL(https://ayase.cn/dshd/),禁止把中继/ws当 SPA。用户可见文案称 dshd daemon / dshd 配对,不出现 ChisaCode 品牌名。 -
主进程窄 import:
loadServerApi只引pairing-offer.js+relay-device-credential-store.js两个兄弟模块并镜像DSH_VENDOR_PACKAGES(parity 测试钉住 vendored 源);exports.js全量 barrel(数万模块,ESM 同步加载会冻结主线程)只允许经 launch file 进 daemon 子进程。 -
daemon 子进程契约:runner 在
asarUnpack;stdout 只有 JSON 行(控制行 + pino json);stdinstop与 stdin 关闭都必须优雅停(孤儿零容忍);意外退出必须落snapshot.error并保留弹窗重试;不做自动退避重启循环(对齐上游)。 -
DSHD_ 命名桥*:桌面对外只有
DSHD_CHISACODE_HOME(打包需DSHD_ALLOW_ENV_HOME=1,同 dsh-home 守卫)与DSHD_DSH_VENDOR_DIR;CHISACODE_*只允许出现在 daemon 子进程 env 注入处,主进程自身 env 与 PTY /dsh web子进程永不携带;字面量DSHD_HOME属 dsh-home 卡,不可占用。DEEPSEEK 凭据只经official-deepseek-env白名单入子进程 env,launch JSON 永不含密钥。 -
snapshot.relayConnected/relayError反映真实 relay control;未连接时弹窗明示且不展示配对码。 -
源码启动若缺
dist会构建 ChisaCode server;pack/dist 额外组装并验证 production daemon 依赖,禁止靠构建机残留产物。 -
侧栏 QR 仅客户端
qrSvg(pairingUrl)(includeQr: false)。 -
服务器中继禁止
chisacode.sh/ 上游account_id。AGPL:AGPL-SHIPPING.md。内置ayase.cn:443是 TLS 传输默认,不可作 SPA;公网 SPA 由同域 nginx 提供https://ayase.cn/dshd/,中继只占精确/ws与/health路由。 -
粘性:
deviceSecret直至用户解除配对;刷新 QR 只换短期 pairing token。 -
设备名(2026-09-04 起): 配对 hello 的
relayDeviceAuth.deviceName(append-only 协议字段,trim 后 1–120)是客户端自报的设备名——手机配对页从 UA 派生(iPhone · iOS 18.2/Android 15 · Pixel 8/电脑,兜底设备,见mobile/web/chisacode/session.js#deviceNameFromUa),daemon 存为 device label(旧客户端兜底relay-pair)。改名走 IPCshell:rename-remote-device→DshdRemote.renameDevice→RelayDeviceCredentialStore.renameDevice(文件落盘、幂等、封顶 120、拒绝已吊销);两条标签写入路径(签发/改名)都归一 120 预算——DeviceRecordSchema在加载时封顶label,超长持久化标签会让整个 store 文件加载失败。存量relay-pair行不自动改,用户手动改名即迁移。fork 合同见vendor/chisacode-remote/DESKTOP-FORK.md。 -
dsh-im 桌面内置:insert 在自有 overlay
desktop-plugins/dsh-im/desktop-dsh-im.patch.yml,--patch叠加(full+skip);cordis.patch.yml不写受管块(只 strip 迁移);禁插件 / Recovery 不可关(IPC 返回desktop-builtin,config 归一化剔除别名);vendor 运行时缺损 fail start(skip 修不了)。 -
渠道主操作 36px(飞书扫码无
size=small)。 -
断管不崩:vendored
resolveDshVendorDir的execSync必须携带显式stdio(tripwire 在remote-epipe.test.js);主进程 stdout/stderr 常驻stdio-guard(断管类流错误吞掉,uncaughtException 仅吞断管写入、其余复刻 Electron 默认对话框)。 -
弹窗失败态可见:启动中
startingHint;持久失败人话(端口占用 / 通用);On 对!listening或无 pairingUrl 可重试;打开弹窗立刻 refresh 且缺码时至多一次 sync 自愈;弹窗无 raw relay code、无裸#offer=文本;HarnessController关停走stopDaemon(),引导期 sync 失败必进 dsh 日志。 -
qa:remote必含cold.openShowsQr/cold.noBareOfferText/cold.copyAndRotateControls;第二 Electron 冷 boot(DSH_QA_REMOTE=cold,开窗前禁止setRemote);QR 只认[data-dsh-remote-qr];中继未连时这三条断言「无码 + 无复制/刷新 + 有 status」。prestart-ensure校验copyLink/data-dsh-remote-copy-link。 -
桌面 harness 完备(12 个 dsh vendor 包均有
lib/index.js)时才向子进程注入CHISACODE_DSH_VENDOR_DIR;优先级DSHD_DSH_VENDOR_DIR> 继承的CHISACODE_DSH_VENDOR_DIR> 完备自带目录 > 不设(子进程内保留已加固的 npm 全局回退)。 -
dsh-acp-demoshim 仅在 harness acp-demo 构建产物存在时物化(<home>/bin,prepend 子进程 PATH);产物缺失时 provider 如实显示不可用,禁止伪造可用性。
Allowed touch
vendor/chisacode-remote/、src/main/dshd-remote.js、src/main/dshd-daemon-runner.mjs、src/main/index.js、src/main/mobile-web-server.js、src/main/stdio-guard.jsvendor/deepseek-harness/packages/client/ui-settings-remote/src/main/remote-patch.js、config.js、src/shared/lan.js、ipc.js/ preload Remote IPCsrc/main/dsh-im-desktop.js、harness-controller.js、plugin-forensics.jsvendor/dsh-im/、本卡、mobile-remote、_kill-http-remote
Do not touch
- 自研中继冒充移植;daemon/hello 切片
- 恢复 HTTP 宿主令牌墙
- 把中继 IP 填进
remoteAppBaseUrl/ QR 落地 - 把 dsh-im 退回可禁用户插件
Gates
| Kind | What |
|---|---|
| IM | npm --prefix vendor/dsh-im run test:desktop;DSH_IM_LIVE_TEST=1 node --test vendor/dsh-im/host-protocol-live.test.mjs;node vendor/dsh-im/plugin-src/host/build.mjs;真实平台账号收发不以模拟测试代替 |
| Automated | dshd-remote.test.js;dshd-daemon-runner.test.js(runner 协议 + dist-gated 真实 daemon 端到端);remote-epipe.test.js;stdio-guard.test.js;lan.test.js;dsh-im-desktop / skip-compose;ui-settings-remote specs;mobile/web/chisacode/session.test.js(配对 deviceName 上报) |
| Manual | 中继已连接 → 扫码配对 → sticky 重连 → 解除;Windows 打包机:子进程隔离下配对 + 强杀主进程无孤儿 daemon;dev 机(harness 已构建):手机端 dsh provider 建会话 |
Sources
-
Decision: none
-
Plan:gateway_product_redo / fix_qr_pairing / 2026-08-28-remote-epipe-hardening
-
Vendored:
vendor/chisacode-remote/DESKTOP-FORK.md