aps-agent/docs/architecture/desktop.md

92 lines
5.1 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.

# 桌面端与 Web 双形态
> 对标 Codex:桌面安装后用户主目录出现 `~/.aps`;同一套 UI 也可纯 Web 部署。
## 目录约定(对标 Codex `~/.codex`)
桌面端安装到电脑后,**固定**写到用户主目录(不是安装目录):
| 系统 | 路径 |
| --- | --- |
| Windows | `%USERPROFILE%\.aps` → 如 `C:\Users\<user>\.aps` |
| macOS / Linux | `~/.aps` |
```
~/.aps/ # 本机应用数据(会话 / DB / Skill…)
├─ sessions/
│ └─ workspace.json # 项目元数据 + 话题会话 + 消息
├─ skills/
├─ data/ # world.json / master.db / knowledge…
├─ cache/ tmp/ logs/ packs/
└─ config.json
<用户自选工程目录>/ # 新建项目时指定;排产业务文件放这里
├─ 订单 / 物料 / 工艺 Excel…
└─ …
```
- **话题会话**:存在 `~/.aps/sessions/`,可不绑定项目(独立话题)。
- **工程项目**:可选;创建时指定 `workDir`,业务数据文件由用户放在该目录。
| 变量 | 含义 |
| --- | --- |
| `APS_MODE` | `desktop` \| `web`(默认 `web`) |
| `APS_HOME` | 显式主目录(覆盖默认) |
| `APS_SKILLS_PATH` | 单文件 skills.json(测试兼容) |
| `APS_WORLD_PATH` / `APS_DB_PATH` / … | 单项覆盖 |
`GET /api/system/paths`、`GET /api/skills` 的 `skillsDir` / `mode` 可查看当前解析结果。
## 开发命令
在**仓库根**、`apps/web` 或 `apps/desktop` 均可执行(脚本会自动定位仓库根):
```bash
# 建议先在仓库根装依赖
cd ../.. # 若当前在 apps/desktop
npm run bootstrap
npm run dev:web # FastAPI + Vite(浏览器)
npm run dev:desktop # FastAPI + Vite + Electron(数据 → ~/.aps)
# 也可拆开(仅仓库根):
npm run dev:server
npm run dev:ui
```
## 打包
```bash
npm run build:web # 产出 apps/web/dist —— 静态资源,部署到 Nginx/CDN,API 另部服务端
npm run build:sidecar # 固定 CPython + 哈希锁依赖 + PyInstaller + 冻结产物冒烟
npm run build:desktop # Web + Sidecar + electron-builder Windows NSIS 安装包
```
- **Web 部署**:只部署 `apps/web/dist` + 后端进程(uvicorn / 容器);`APS_MODE=web`。
- **桌面分发**:安装包内含 `resources/sidecar/aps-sidecar.exe` 及其私有运行库,不调用 PATH 中的 Python;首次运行创建 `~/.aps`,Skill 写入 `~/.aps/skills/<id>/`。
Sidecar 构建固定使用 uv-managed Windows x64 CPython 3.13.12。`packaging/requirements-sidecar.lock` 精确锁定全部直接和传递依赖及 wheel hash;构建时强制 `--only-binary :all:`,并在产物生成后执行 NumPy、Pandas、OR-Tools CP-SAT 和真实 `/api/health` 冒烟。主要产物:
- `dist/sidecar/aps-sidecar/`:PyInstaller onedir Sidecar;
- `apps/desktop/release/win-unpacked/`:可直接冒烟的展开目录;
- `apps/desktop/release/aps-agent-desktop-<version>.exe`:NSIS 安装包。
安装态启动顺序为:Electron 预留 loopback 随机端口并生成请求侧 nonce,启动内嵌 Sidecar;只有当前 Electron session 会为当前 Sidecar origin 注入 `x-aps-sidecar-nonce`,缺失或错误 nonce 的请求在进入 FastAPI 前返回 403。Electron 等待带相同 nonce 的 `/api/health` 成功后才加载同源 Web UI。每次崩溃重启都会轮换端口和 nonce、清除旧 origin,并在新实例健康前把窗口冻结到 `about:blank`。renderer 启用 sandbox;CSP、默认拒绝权限请求、导航与重定向锁、HTTPS 外链限制和 IPC sender 校验共同约束当前 origin;应用使用单实例锁,Sidecar 固定单 worker 并只继承允许列表环境。标准输出和错误写入 `~/.aps/logs/sidecar.log`,单文件 10 MiB 轮转;意外退出最多重启 3 次,Electron 正常退出会回收进程树,Electron 异常消失时 Sidecar 的父进程看门狗会自行退出。
本机 Windows 构建和打包 Electron CDP 冒烟已证明产物不依赖系统 Python、renderer 可加载真实 Sidecar origin,且绕过 Electron 直接访问健康端点会被 403 拒绝。桌面依赖已升级到 Electron 43.2.0 和 electron-builder 26.15.3,使用官方 npm registry 的当前审计结果为 0。正式 stable 发布仍须在无 Python、无网络的干净 Win10/11 x64 虚拟机完成安装、20 次冷启动、Defender、代码签名、升级/回滚及中文/空格安装路径验收。
## 原生 / 顶栏菜单
Windows 桌面端使用**无边框窗口**(`frame: false`)+ 自绘顶栏:
1. 中文菜单 `文件 / 编辑 / 视图 / 窗口 / 帮助` 贴窗口最顶
2. 顶栏空白区可**拖动窗口**;双击空白可最大化/还原
3. 右侧自绘 **最小化 / 还原·退出全屏 / 关闭**(不依赖系统 overlay,避免点不动)
右侧面板拖拽上限随窗口宽度计算:只保证对话区 ≥280px。
## Skill 与旧「设置页卡片」的区别
旧实现是服务端 `server/data/skills.json` 的登记表。
现实现对标 Codex:Skill 是用户目录下的**文件夹资产**;管理台展示并维护 `manifest.json`,桌面/Web 共用同一套 API。