<!-- Source: https://deepseek-browser-use.io.nexus/35 -->

# 后端自动管理：安装 Java 与 Git、更新源码、编译和启动

原生插件 0.2.0 增加 `dsb_backend`。启用后，Windows 用户不必先手工起 Java 服务：插件检查依赖、克隆源码、执行 Maven 构建，再以隐藏窗口方式启动长驻后端。浏览器动作仍直接走 HTTP。

## 1. 默认部署位置与来源

Windows 存在 D 盘时，默认源码目录为：

```text
D:\project\project-litongjava\deepseek-browser-use
```

没有 D 盘时使用当前用户目录下的 `project/project-litongjava/deepseek-browser-use`，也可配置绝对路径 `backendRepoDir`。

初次克隆优先使用 [Gitee 仓库](https://gitee.com/ppnt/deepseek-browser-use)，失败后尝试 [GitHub 仓库](https://github.com/litongjava/deepseek-browser-use)。`backendRepository:github` 可以交换首选顺序。使用 HTTPS，无须提前配置 SSH key。

克隆先落在新建的同级暂存目录，成功后移动到目标目录。目标目录已存在但不是 Git 仓库时直接报错；克隆失败的暂存目录保留供排查，不删除或覆盖用户已有文件。现有仓库更新使用其 origin，不在 fetch 失败时偷偷切换来源。

## 2. 自动安装哪些依赖

| 依赖 | 检查/安装方式 |
| --- | --- |
| Git | 优先复用 PATH；缺失时执行 `winget install --id Git.Git --exact --source winget` |
| JDK | 检查 JAVA_HOME、PATH 和常见安装目录；必须有 Java 21+ 与 javac，缺失时安装 `Microsoft.OpenJDK.21` |
| Maven | 优先复用 `mvn.cmd`；缺失时从 Apache 存档站下载 3.9.16 ZIP，用同目录的 `.sha512` 侧车文件校验，再解压到仓库父目录 `.dsb-tools` |

winget 使用静默安装和协议接受参数。Java 官方安装入口见 [Microsoft OpenJDK 文档](https://learn.microsoft.com/en-us/java/openjdk/install)，Maven 发布页见 [Apache 下载页](https://maven.apache.org/download.cgi)，脚本实际取用的存档源和 `.sha512` 侧车文件在 [archive.apache.org](https://archive.apache.org/dist/maven/maven-3/3.9.16/binaries/)。下载失败、checksum 不匹配或包安装失败都会终止准备，不解压或执行未验证的文件。

已有可用依赖不会重复安装。脚本只为子进程设置 JAVA_HOME 与 PATH；Maven 便携安装不修改系统环境变量。若 winget 缺失、安装需要人工提权，或新装依赖仍无法识别，会保留诊断并提示手工安装/重开 Harness。

这一版自动依赖准备支持 **Windows x64**；macOS/Linux 可以继续安装好服务后使用 `backendAutoStart:false` 的外部 HTTP 模式。源码生产构建不下载内嵌 Chromium，默认浏览器需要本机已有 Chrome；其他引擎按服务文档配置。

## 3. 插件配置

```yaml
- insert:
    - id: litongjava-browser-use
      name: '@litongjava/dsh-plugin-deepseek-browser-use'
      config:
        baseUrl: http://127.0.0.1:10059
        browser: chrome
        headless: false
        backendAutoStart: true
        backendAutoUpdate: true
        backendInstallDependencies: true
        backendRepoDir: D:/project/project-litongjava/deepseek-browser-use
        backendRepository: gitee
        backendStartupTimeoutMs: 120000
```

| 配置 | 默认值 | 行为 |
| --- | --- | --- |
| `backendAutoStart` | 随包 patch 为 true，裸 Config 为 false | 激活后先探测健康，健康则直接复用；否则在后台准备并启动，浏览器调用等待就绪 |
| `backendAutoUpdate` | true | 停止状态的后端启动前 fetch 并快进更新 |
| `backendInstallDependencies` | true | 自动安装缺失工具；设 false 时只检查并报告缺失项 |
| `backendRepoDir` | 上述默认目录 | 专用源码 checkout，建议不要用日常有未提交修改的开发目录 |
| `backendRepository` | gitee | 首次克隆的首选源，另一源作为失败后备 |
| `backendStartupTimeoutMs` | 120000 | Java 启动后的健康检查期限，不包括下载与编译 |

托管模式只接受 `http://127.0.0.1:端口` 或 `http://localhost:端口` 根地址。HTTPS、远程主机和反向代理路径应使用外部服务模式。默认包仍使用 10049；本次部署发现该端口已有服务，因此示例与实际新实例使用 10059。

同一源码目录只能托管一份进程状态；多实例应使用不同的源码目录和端口。

## 4. 后台操作与查询

`dsb_backend` 接收一个参数：

```json
{"action":"start"}
```

立即返回运行中状态；之后调用：

```json
{"action":"status"}
```

| action | 作用 |
| --- | --- |
| `status` | 读取当前管理操作的 running/done/failed、日志尾部和结果，不启动新操作 |
| `inspect` | 异步刷新服务健康状态、进程归属和持久状态；再用 status 读结果 |
| `prepare` | 安装缺失依赖、克隆/按配置更新并编译，不启动服务 |
| `start` | 已健康时直接复用；否则准备并启动 |
| `update` | 显式 fetch/快进并编译，运行中的后端不被重启，必要时返回 restartRequired |
| `restart` | 先准备新版本；检查自有进程且无活动浏览器任务后重启 |

同一插件管理器一次只运行一项操作，跨进程还有独占文件锁，防止并发 clone/build。调用者取消等待不会中断其他会话依赖的共享安装；可继续用 status 查询。准备失败后必须显式 start/prepare 重试，普通浏览器动作不会不断触发安装。

`status` 的外层 `ok` 表示管理操作是否失败；服务是否健康还要看完成结果中的 `healthy`。`inspect` 操作本身成功并不代表服务已启动。

## 5. 自动更新的边界

更新使用 `git fetch origin` 和 `git merge --ff-only`。以下情况终止，不 reset、不 stash、不覆盖本地代码：

- origin 不属于指定 Gitee/GitHub HTTPS 仓库。
- 工作区存在已修改或未跟踪文件。
- 分支的上游不是 `origin/`，或存在领先上游的本地提交（分支完全没有上游时，报的是 git 命令自身的失败信息）。
- 网络、依赖下载或 Maven 编译失败。

更新触发点是 **停止状态的后端启动前**，不是定时热更新。已运行的健康服务直接复用，并返回 `updateDeferred`；用户可执行 update 预编译，然后在关闭浏览器任务后 restart。此功能更新 Java 后端源码，不自动升级插件 npm 包。

构建命令为：

```powershell
mvn -B -ntp -Pproduction -pl playwright-server -am clean package -DskipTests -Ddriver.platform=win32_x64
```

默认部署构建跳过 Java 测试，测试仍由开发和发布流程负责。成功后把 fat JAR 复制到 `.dsb-backend/releases/<commit>/backend.jar`，同 commit 已有发布文件时复用。运行中的旧 JAR 不被覆盖，编译失败不会影响已有进程。

## 6. 进程、日志与恢复

```text
源码目录/.dsb-backend/
  state.json                   PID、随机实例标识（token）、commit、JAR 与日志目录
  releases/<commit>/backend.jar
  runs/<实例标识>/
    app.properties
    stdout.log
    stderr.log
  profile/                     托管浏览器独立 profile
```

`.dsb-backend` 写入该 checkout 的 `.git/info/exclude`，运行文件不会让自动更新一直认为工作区脏。后端 profile 独立于原先手工启动的服务，首次进入网站可能需要重新登录。

管理日志另外保存在 `~/.deepseek-browser-use/operations/<操作>-<随机值>/`：`config.json`、`operation.log` 与 `result.json`。插件只展示有上限的日志尾部，完整诊断留在磁盘。

启动使用隐藏窗口。Java 的日志直接写文件，避免 Windows 子进程继承管道导致 Harness 误以为启动过程一直未完成。启动前会先复查健康状态并核对端口占用（已被占用即报错），健康等待期间再核对端口监听 PID，不能把其他进程的健康响应当作本次启动成功。

重启先核验配置端口、state 中的服务地址、PID、随机实例 token（构造 `-Ddsb.managed.instance`）、进程命令行和端口归属，再查询任务数。任务数非零或无法确认时拒绝重启；只在核验通过后关闭浏览器并停止自己的 Java 进程。插件不会仅凭 PID 文件杀进程，也不会重启原来在同一端口运行的外部服务。

Java 活着但不健康时不重复启动；健康等待超时会保留日志与状态供处理。当前版本不自动回滚启动失败的新版本，应先检查日志，再选择已保存的旧 JAR 恢复。插件退出只清理会话任务，后端进程继续运行，以便后续会话复用。任务关闭、取消作业与查询既有作业不会为了清理而重新安装或拉起已停止的后端；后端崩溃重启后，旧页面和作业不自动恢复，需要新建浏览器会话。

## 7. 本次验证与部署

已从 Gitee 克隆到 `D:\project\project-litongjava\deepseek-browser-use`，使用已有 Java 21.0.6、Git 2.49.0 和 Maven 3.8.8 完成 production 构建，服务地址为 `http://127.0.0.1:10059`。原 10049 服务保持运行。

验证包括健康检查、真实浏览器导航、中文输入、点击回读、上传、截图、异步批次、源码更新检查、受管进程空闲重启，以及存在活动任务时拒绝重启。

自动化测试覆盖管理器并发合并、日志上限、取消等待、失败后不重复安装、本机地址限制（TypeScript 侧校验）、PowerShell 状态读取、拒绝重启外部服务和保护脏工作区。由于机器已有 JDK/Git/Maven，本次没有卸载依赖来重跑安装器；缺失依赖安装分支需在干净 Windows 环境进一步验证。
