Files
dsh_ai1net_server/交付物/Android壳联动WorkBuddy手机回复-联动方案-20260928.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

174 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Android 壳 × WorkBuddy 手机回复 · 联动方案(2026-09-28)
> **需求(用户原话)**:能否联动 `ai1net-dsh-anywhere` 中的会话(负责开发 Android app、配合实现这个功能)**在我的 Android 手机上运行**,共同实现「手机回复 WorkBuddy 会话」这个效果。
> **上游**:`交付物/手机回复WorkBuddy会话-架构与实施方案-20260928.md`(本文件是它的**手机端落地补充**,⛔ 不改其架构结论)。
> **证据分级**:`【已验】`有实测读数 | `【源码在】`代码在位未跑 | `【待核实】`未取证 —— 交付时不得混写。
---
## 0 判定(三句话)
1. **能联动,而且 Android 壳正好补上原方案最弱的一环**(手机端形态 + 通知能力)。
2. **但先纠正一处事实**:那个 Android app **确实存在**(`E:/github/dsh-client/apps/android`,Capacitor 壳),但它处于 **M3「骨架(不构建)」** 阶段 —— **WebView 只加载一张骨架说明页**,且 **当前机器已无构建环境**。所以不是"接线即可用",而是"**壳有了、内容与构建链要补**"。
3. **链路天然同构**:那条线(手机接入线)的通道是「手机 → 门户 → 中继 → 设备垫片 → 桌面 **DSH**」;本方案要的是「手机 → 门户 → 中继 → 设备桥 → 桌面 **WorkBuddy**」。⇒ **同一个手机端、同一个设备节点、同一条中继,只是目标从 DSH 换成 WorkBuddy**。⛔ 不新造任何传输。
---
## 1 事实核查(Android app 到底什么状态)
### 1.1 它是什么
| 项 | 事实 |
|---|---|
| 位置 | `E:/github/dsh-client/apps/android`(属 **`dsh-client` monorepo**) |
| 仓定位 | `dsh-client — DSH 客户端(桌面 + Android)`,**一份内核 + 多套壳**(README 原话) |
| 形态 | **Capacitor 8.5.2 壳**(`@capacitor/core` + `@capacitor/android`) |
| 标识 | appId `com.dsh.client` | appName「DSH 客户端」| `webDir: www` |
| 阶段 | **M3 · 骨架(不构建)**,自报能力档 **C0**;`hasLocalPlatform: false`、`connectionMode: 'remote-only'`、TUN/保活 = `pending(C 档原生)` |
| WebView 当前加载 | 本地 `www/index.html`(**3.5 KB 骨架说明页**,09-18 编写)—— **不是功能页** |
| 地址策略 | 明文规定「平台地址一律**运行时注入**,⛔ 不写死在配置里」—— 与本方案一致 ✅ |
### 1.2 关键读数
| # | 读数 | 结论 |
|---|---|---|
| 1 | `app/build/outputs/apk/debug/app-debug.apk` **4,118,462 B · 09-18 00:12**【已验】 | **曾成功构建过**,可直接装到手机先跑 |
| 2 | `java` **未装** | `ANDROID_HOME`/`ANDROID_SDK_ROOT` **未设** | 默认 SDK 目录**不存在**【已验】 | **现在出不了新包** ⇒ 要出新 APK 必须装 **JDK 17 + Android SDK(约 2–4 GB)** |
| 3 | `capacitor.config.ts` 顶部原文 | 「本阶段**不构建**……那是**资源承诺**,须用户确认后单独做」 |
| 4 | `dsh-client` 仓 `git log` | `your current branch 'master' does not have any commits yet`;`git status` 全部 `??` ⇒ **零提交、全部未跟踪**【已验】 |
| 5 | `packages/` 五个包 | `core`(端无关内核)· `adapter-mobile`(**移动端自适应适配层**)· `device-shim`(设备垫片)· `portal-first-screen` · `subagent-local` |
### 1.3 那条线交付的、本方案可直接用的三件
| 件 | 作用 | 对本方案的意义 |
|---|---|---|
| **`packages/adapter-mobile`** | 断点 token + 移动端适配(⛔ 不改上游 `ui-theme`/`ui-layout`) | 让「桌面 UI 在手机上可用」这件事**已经有解** |
| **`packages/device-shim`** | 只绑 `127.0.0.1:20090` 的 HTTP+WS 反代,进程内注入 DSH token | **本方案「设备侧桥」的现成范式**(照它的收窄纪律做,⛔ 不重发明) |
| **`packages/core`** | 端能力 provider(`tunUp`/`keepAlive`/`reportState`/`requestPermission`)+ 能力档 C0–C3 + 降级 | 手机端要做原生能力(通知/保活)时,**声明与降级的框架已就位** |
### 1.4 🔴 两个现存阻断(不修就动不了)
1. **`E:\ProgramDSH` 整棵树已消失**【已验】⇒ 那条线引用的 `E:\ProgramDSH\.dsh\profiles\desktop\`(设备垫片的挂载点)**不存在** ⇒ 垫片无法挂载(该线自己的接续包还在说"`E:\ProgramDSH\.dsh\` 未搬、路径保持原样")。
- 已找到替代:`C:\Users\Administrator\.dsh` **存在**且含 `profiles/`、`scripts/`、`sessions/`(但**无 `temp/`**)⇒ 需先把运行时家目录的落点钉死,再谈继续开发。
2. **构建环境缺失**(§1.2 读数 2)⇒ 出新 APK 需要 JDK 17 + Android SDK。
---
## 2 联动架构
### 2.1 一张图(同一个手机、同一条中继、两个目标)
```
┌──────────────── Android 手机 ────────────────┐
│ DSH 客户端(Capacitor 壳) │
│ ├ 入口页:两个卡片(本次新增) │
│ │ ① 打开桌面 DSH ② WorkBuddy 会话 │
│ └ WebView(同一壳内切换 URL) │
└───────────────────┬──────────────────────────┘
│ HTTPS 443(门户登录态)
▼
服务器节点 47(+ ai1net 插件)
├ 门户 / 账号 / 设备台账 / IM 内核 (既有)
├ 配对 overlay-pair(28 条判据全绿) (既有)
├ 覆盖网络中继(443 兜底,设备只拨出) (既有)
├ 通道① 路径前缀 /u/<slug>/desk/<hostId>/* (既有)
└ 通道② 移动会话面 /mobile.html + M6 模块 (本方案新增)
▲ wss 反隧道(⛔ 无公网入站口)
│
客户端(+插件)= 用户电脑(同一个设备节点)
├ 设备垫片 127.0.0.1:20090 → 桌面 DSH Web (既有,通道①)
└ 设备侧桥 127.0.0.1:<口> → WorkBuddy 钩子 (本方案,通道②)
```
🔴 **关键点**:**两条通道共用同一个设备节点与同一条中继** —— 手机侧与平台侧的配对、登录、台账、取址**全部复用**;差异只在"设备侧那一段对接谁"(DSH Web ↔ WorkBuddy 钩子)。
### 2.2 通道②的两种手机端形态
| 形态 | 做法 | 优点 | 缺点 |
|---|---|---|---|
| **PWA(推荐先行)** | 手机浏览器打开平台移动会话页 →「添加到主屏幕」 | **零资源承诺**、当天可用、支持 Web Push 通知、迭代无需打包 | 后台保活弱;iOS 更受限(本方案只针对 Android) |
| **Capacitor 壳(推荐后补)** | 壳的 `server.url` 指向平台移动会话页;壳只做容器 | 通知/保活/TUN 可走原生;会话持久;像一个真 App | **需 JDK 17 + Android SDK(2–4 GB)**;需重打包 |
🔴 **一条重要的架构建议**:壳**只设一次 `server.url` 指向平台页面**,此后所有功能迭代都在**服务器侧**完成 ⇒ **APK 成为稳定薄容器,不需要为功能变更重新打包**。这是把"2–4 GB 构建环境"从"每次都要"降为"一次性"的关键设计。
### 2.3 Android 壳带来的、浏览器给不了的三件事
1. **通知**(Android 通知渠道)—— "手机回复"的核心体验:桌面会话停下来等你时,手机该响。
2. **后台保活** —— 浏览器切后台即被挂起;壳内可争常驻(属 C 档原生,**待补**)。
3. **会话持久** —— 登录态与设备绑定存在 app 内,扫码一次之后长期有效。
⛔ 但**不要**现在就许诺 TUN/`VpnService`:按那条线自己的设备矩阵,它属 **C 档「每端必写原生」**,目前 `canCreateTun: false`、`canKeepAlive: false` 是**如实自报**,⛔ 不许假装。
---
## 3 与上一版方案的合并(谁做什么)
| 上一版方案的件 | 本方案的手机端承接 | 说明 |
|---|---|---|
| `web/mobile.html` 移动会话页 | **壳的 WebView 目标(或 PWA 入口)** | 页面本身不变;Android 只是它的容器 |
| M6「移动会话面」模块(3 条精确路由) | 不变 | 手机侧调的就是这三条 |
| 设备侧桥 `wb-mobile-bridge` | 与 `device-shim` **同节点、同纪律**(只绑回环 + 内部注入) | ⛔ 不新造第二套范式 |
| WorkBuddy 钩子分支 | 不变(`permissionDecision` + `additionalContext`) | 壳对这一段**不可见**,也无需可见 |
| 覆盖网络 / 配对 / 台账 / 四道闸 | **全复用** | 手机换壳不改变平台侧任何判据 |
⇒ **合并后的手机端 =「一个 Android 壳 + 两个入口卡片」**;平台侧 = **既有 + M6**;桌面侧 = **既有垫片 + 设备侧桥**。
---
## 4 分阶段路径(每棒可机器验,⛔ 做完即停)
| 棒 | 目标 | 判据(可机器验) | 资源 |
|---|---|---|---|
| **A0** | **零成本先跑通**:装既有 `app-debug.apk` 到手机,确认壳能起、能显示骨架页 | 手机上出现「DSH 客户端」图标且能打开 | **0**(用既有 APK) |
| **A1** | 修两个阻断:钉死 dsh 运行时家目录落点 + 恢复设备垫片挂载 | 垫片起、`curl 127.0.0.1:20090/` 返回 **200**(垫片自检 17 断言绿) | 0 |
| **A2** | **PWA 先行**:平台移动会话页上线 + 手机加到主屏幕 | 手机打开该页 **200**;能看到待答项;作答后桌面会话体现所选 | 0 |
| **A3** | 手机端原生形态:壳 `server.url` 指向平台页面 + 通知 | 重打包后壳内可打开该页;桌面停下时手机收到通知 | **JDK 17 + Android SDK(2–4 GB)** ← 🔴 唯一资源承诺 |
| **A4** | 真机端到端 + 两线合并验收 | ① 通道①:手机进桌面 DSH 并发一条消息 ② 通道②:手机回复 WorkBuddy 并看到模型据此继续 ③ 既有 28 条判据零回归 | 0 |
---
## 5 唯一需要拍板的事
**问题**:是否现在装 **JDK 17 + Android SDK(约 2–4 GB)**,以产出带"通知 + 平台地址"的新 APK?
**为什么需要你定**:这是**磁盘与安装时间的一次性资源承诺**(属边界外第②类);而且**不装也能先看到效果**(A0 用既有 APK 验证壳、A2 用 PWA 把功能跑通),只是拿不到原生通知与保活。
- **候选 1 · 先不装,走 A0 → A2(PWA 先行)**
- 优点:零成本、当天可验、功能链路一次走通;失败也不留包袱。
- 缺点:没有原生通知(要开浏览器才看得到待答);后台保活弱。**倾向先走这条**。
- **候选 2 · 现在就装(A0 → A1 → A2 → A3 一次做完)**
- 优点:一步到位拿到通知与常驻,体验完整。
- 缺点:先付出 2–4 GB 与安装时间;而壳内要显示的页面(A2 的产物)**此时还不存在** ⇒ 有白装的风险(建议至少等 A2 出页之后再装)。
- **倾向**:**候选 1** —— 先零成本把链路跑通,A2 出页后再决定是否装 SDK;那时装也只需一次,且此后页面迭代不再需要打包。
---
## 6 风险与未验证项(⛔ 不得当成已定)
1. **壳内切 URL 的实现方式【待核实】** —— 现有 `capacitor.config.ts` **未设 `server.url`** ⇒ 当前只能加载内置 `www`;要把 WebView 指到平台页面,**至少需要一次重打包**(或确认壳是否支持运行时注入)。这一点直接决定 A3 是否真的必需。
2. **既有 APK 是否可复现【待核实】** —— 09-18 那个 APK 是当时环境构建的;当前无 Java/SDK ⇒ 若它跑不起来,A0 就不能零成本验证。
3. **`C:\Users\Administrator\.dsh` 是否为权威家目录【待核实】** —— 该目录无 `temp/`(原 `E:\ProgramDSH\.dsh\temp\joint\` 里的台账看不到)⇒ 需确认它是"搬过来的"还是"另一份"。
4. **设备垫片挂载点失效** —— 那条线写死的 `E:\ProgramDSH\.dsh\profiles\desktop` 已不存在;**先修这个**,否则通道①本身就不通(更谈不上与通道②合并验收)。
5. **`dsh-client` 仓零提交** —— 全部 untracked ⇒ 无版本历史、回滚只能靠文件副本;动它之前建议先入库。
6. **Android 后台保活是系统级难题** —— 按那条线自己的表述属 C 档「每端必写原生」;⛔ 不要因为"壳里能跑"就假设常驻可用。
7. **两条通道会共用设备节点** ⇒ 端口声明(`ports`)、守护编排、开关都要**各管一份**,⚠️ 别把通道②的开关错接到通道①上。
---
## 附:本次取证命令与读数(可复跑)
| # | 取证点 | 读数 |
|---|---|---|
| 1 | `find E:/github/dsh-client/apps/android -name "*.apk"` | `app/build/outputs/apk/debug/app-debug.apk`(4,118,462 B · 09-18 00:12) |
| 2 | `cat apps/android/package.json` | `@capacitor/core 8.5.2`;描述「Capacitor 壳骨架 + 端能力声明;**本阶段不构建**」 |
| 3 | `cat apps/android/capacitor.config.ts` | `appId com.dsh.client`;`webDir www`;**无 `server.url`**;注释明写"地址运行时注入"+"JDK17+SDK 属资源承诺" |
| 4 | `cat apps/android/src/endpoint.ts` | 自报 `declaredTier: 'C0'`、`hasLocalPlatform: false`、`canCreateTun/canKeepAlive/canReportState: false` |
| 5 | `cat apps/android/www/index.html` | 3,544 B 骨架说明页(非功能页) |
| 6 | `which java` / `$ANDROID_HOME` / SDK 目录 | 未装 / 未设 / 不存在 |
| 7 | `git -C E:/github/dsh-client log` | `does not have any commits yet`;status 全 `??` |
| 8 | `ls E:/github/dsh-client/packages` | core · adapter-mobile · device-shim · portal-first-screen · subagent-local |
| 9 | `ls -d E:/ProgramDSH/.dsh/profiles/desktop` | **不存在**(`E:\ProgramDSH` 整棵已消失) |
| 10 | `ls C:/Users/Administrator/.dsh` | 存在(含 `profiles/` `scripts/` `sessions/`;**无 `temp/`**) |
| 11 | anywhere 线入口 §34 / §24 | 「手机侧**零新增客户端**(门户登录态 + 官方 Web UI,走路径前缀)」 |
| 12 | `packages/adapter-mobile/package.json` | 「移动端自适应适配层 —— dsh 独立插件形式,⛔ 不改上游 ui-theme / ui-layout」 |