{"_id":"@aixyzstudio/zcode-webui","_rev":"4-55f1649e2bb8d4423fe8e5f52b372f19","name":"@aixyzstudio/zcode-webui","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@aixyzstudio/zcode-webui","version":"0.1.0","keywords":["zcode","glm","bigmodel","zai","coding-agent","webui","code-server","browser"],"license":"MIT","_id":"@aixyzstudio/zcode-webui@0.1.0","maintainers":[{"name":"windviki","email":"windviki@gmail.com"}],"homepage":"https://github.com/windviki/zcode-webui#readme","bugs":{"url":"https://github.com/windviki/zcode-webui/issues"},"bin":{"zcode-webui":"src/cli.mjs"},"dist":{"shasum":"26300faa5fc6323804c2d161531336348c78685d","tarball":"https://registry.npmjs.org/@aixyzstudio/zcode-webui/-/zcode-webui-0.1.0.tgz","fileCount":22,"integrity":"sha512-MLKcDwanN7k4vRgIMmNzswYwg9nL5aY2Dbm/96w0GSyeaTWO4zKdCJnaA1C4Dzn6H4+3vIgh+EamWXHp/Fa5lg==","signatures":[{"sig":"MEYCIQD5h/ThuYiczhDnRaO1J/5H1YCd36P0JxF0g+cZavb9BAIhANqtytBMIb1jzjGLxy5amgcZy6uzDPoPYC69xYS8+fEu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":194540},"main":"src/server.mjs","type":"module","engines":{"node":">=18"},"gitHead":"0c15497fbdca21321cb8dd514c38652a95ee02f4","scripts":{"cli":"node src/cli.mjs","smoke":"node scripts/smoke-test.mjs","start":"node src/server.mjs","fetch-renderer":"bash scripts/fetch-renderer.sh","prepublishOnly":"node --check src/cli.mjs && node --check src/server.mjs && node --check src/dirs.mjs && bash -n scripts/fetch-renderer.sh"},"_npmUser":{"name":"windviki","email":"windviki@gmail.com"},"repository":{"url":"git+https://github.com/windviki/zcode-webui.git","type":"git"},"_npmVersion":"12.0.2","description":"Run the official ZCode desktop UI in any browser, backed by the official zcode-server runtime, with code-server integration.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ws":"^8.18.0"},"_hasShrinkwrap":false,"devDependencies":{"playwright-core":"^1.62.1"},"_npmOperationalInternal":{"tmp":"tmp/zcode-webui_0.1.0_1787583154691_0.1780706361331783","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aixyzstudio/zcode-webui","version":"0.2.0","keywords":["zcode","glm","bigmodel","zai","coding-agent","webui","code-server","browser"],"license":"MIT","_id":"@aixyzstudio/zcode-webui@0.2.0","maintainers":[{"name":"windviki","email":"windviki@gmail.com"}],"homepage":"https://github.com/windviki/zcode-webui#readme","bugs":{"url":"https://github.com/windviki/zcode-webui/issues"},"bin":{"zcode-webui":"src/cli.mjs"},"dist":{"shasum":"b20c660c9948ce7488dafca94f15ed4d2b1874de","tarball":"https://registry.npmjs.org/@aixyzstudio/zcode-webui/-/zcode-webui-0.2.0.tgz","fileCount":23,"integrity":"sha512-ZIbZ4ijK3xkdwRj2ip0uCZBbbUG/xvrskzQA05SD7GobbGlWFH9PGxc2Gps+1iPHzADm9ve9dDPnqzuUsj3N4A==","signatures":[{"sig":"MEUCIHaQEvzqfDgaS6jED6PioBMbjiyBa9c+kD1k0HKsM3XNAiEA32KPN4hP+o0LIz3LPkcRJgt4Dp1p4QDRqwKauAzNGgM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":228955},"main":"src/server.mjs","type":"module","engines":{"node":">=18"},"gitHead":"ecdf08d24d6dbcd6dbf9236e065fa1add0b2162e","scripts":{"cli":"node src/cli.mjs","smoke":"node scripts/smoke-test.mjs","start":"node src/server.mjs","fetch-renderer":"bash scripts/fetch-renderer.sh","prepublishOnly":"node --check src/cli.mjs && node --check src/server.mjs && node --check src/dirs.mjs && node --check src/upgrade.mjs && node --check web/bootstrap.js && bash -n scripts/fetch-renderer.sh"},"_npmUser":{"name":"windviki","email":"windviki@gmail.com"},"repository":{"url":"git+https://github.com/windviki/zcode-webui.git","type":"git"},"_npmVersion":"12.0.2","description":"Run the official ZCode desktop UI in any browser, backed by the official zcode-server runtime, with code-server integration.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ws":"^8.18.0"},"_hasShrinkwrap":false,"devDependencies":{"playwright-core":"^1.62.1"},"_npmOperationalInternal":{"tmp":"tmp/zcode-webui_0.2.0_1787896960948_0.30735267341070194","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aixyzstudio/zcode-webui","version":"0.3.0","keywords":["zcode","glm","bigmodel","zai","coding-agent","webui","code-server","browser"],"license":"MIT","_id":"@aixyzstudio/zcode-webui@0.3.0","maintainers":[{"name":"windviki","email":"windviki@gmail.com"}],"homepage":"https://github.com/windviki/zcode-webui#readme","bugs":{"url":"https://github.com/windviki/zcode-webui/issues"},"bin":{"zcode-webui":"src/cli.mjs"},"dist":{"shasum":"13817e768aa053361c541f21e52bea296cd182a8","tarball":"https://registry.npmjs.org/@aixyzstudio/zcode-webui/-/zcode-webui-0.3.0.tgz","fileCount":24,"integrity":"sha512-j2E3CHhVadDUfh7K5IThoqLAExMorcTUpaZWW2ffKTYd2VWYfMYOLFyj+ZEORE7shakIB32QDsIr+lpc732F0A==","signatures":[{"sig":"MEQCIGvC+9NTuwk4F8d/yrLtfGSp13dpWGeDqZ9TWaaRucP9AiBXWWoHL07ju8W5naFeJCHVdCl4aZZthYKYY+Tv/Aba4w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":248520},"main":"src/server.mjs","type":"module","engines":{"node":">=18"},"gitHead":"e0def5c42b6a45102c4a9310f8cbd267adcb6655","scripts":{"cli":"node src/cli.mjs","smoke":"node scripts/smoke-test.mjs","start":"node src/server.mjs","fetch-renderer":"bash scripts/fetch-renderer.sh","prepublishOnly":"node --check src/cli.mjs && node --check src/server.mjs && node --check src/dirs.mjs && node --check src/upgrade.mjs && node --check web/bootstrap.js && bash -n scripts/fetch-renderer.sh"},"_npmUser":{"name":"windviki","email":"windviki@gmail.com"},"repository":{"url":"git+https://github.com/windviki/zcode-webui.git","type":"git"},"_npmVersion":"12.0.2","description":"Run the official ZCode desktop UI in any browser, backed by the official zcode-server runtime, with code-server integration.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ws":"^8.18.0"},"_hasShrinkwrap":false,"devDependencies":{"playwright-core":"^1.62.1"},"_npmOperationalInternal":{"tmp":"tmp/zcode-webui_0.3.0_1788397903150_0.10857522895775773","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@aixyzstudio/zcode-webui@0.4.0","bin":{"zcode-webui":"src/cli.mjs"},"bugs":{"url":"https://github.com/windviki/zcode-webui/issues"},"dist":{"shasum":"53c535399115bdeec74d1287f6d7cd05ab87640b","tarball":"https://registry.npmjs.org/@aixyzstudio/zcode-webui/-/zcode-webui-0.4.0.tgz","fileCount":24,"integrity":"sha512-TAuplfjSvwdPURPy6tjrL8U4oAZad3v4EfefFZE2V3CthfzeW64mwvg7xBXdr7FoqQZOXF492hXtG9Rcm6yS4A==","signatures":[{"sig":"MEYCIQCI6ZcYzolh1YnCjENIt+1jVxm4dMPqzd/tC1rqj64n9gIhAMEuOhLbabxL7pngkZWNytJ4TkLp0rIfpoNI6T+urLa5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICzE0PoEkFLtcuKg2JMF1ZvziVymN8R7DUXiNb3UukRGAiAoEHCtraWm05kFb0tozvkz2ZekmddfIXEx48cK2GLyPw=="}],"unpackedSize":270807},"main":"src/server.mjs","name":"@aixyzstudio/zcode-webui","type":"module","engines":{"node":">=18"},"gitHead":"3c0d25632b994716027435b9f92b3ce1cc35b0f4","license":"MIT","scripts":{"cli":"node src/cli.mjs","smoke":"node scripts/smoke-test.mjs","start":"node src/server.mjs","fetch-renderer":"bash scripts/fetch-renderer.sh","prepublishOnly":"node --check src/cli.mjs && node --check src/server.mjs && node --check src/dirs.mjs && node --check src/upgrade.mjs && node --check web/bootstrap.js && bash -n scripts/fetch-renderer.sh"},"version":"0.4.0","_npmUser":{"name":"windviki","email":"windviki@gmail.com"},"homepage":"https://github.com/windviki/zcode-webui#readme","keywords":["zcode","glm","bigmodel","zai","coding-agent","webui","code-server","browser"],"repository":{"url":"git+https://github.com/windviki/zcode-webui.git","type":"git"},"_npmVersion":"12.0.2","description":"Run the official ZCode desktop UI in any browser, backed by the official zcode-server runtime, with code-server integration.","directories":{},"maintainers":[{"name":"windviki","email":"windviki@gmail.com"}],"_nodeVersion":"24.18.0","dependencies":{"ws":"^8.18.0"},"_hasShrinkwrap":false,"devDependencies":{"playwright-core":"^1.62.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/zcode-webui_0.4.0_1788698967670_0.6682889496493336"}}},"time":{"created":"2026-08-24T14:52:34.579Z","modified":"2026-09-06T12:49:27.920Z","0.1.0":"2026-08-24T14:52:34.847Z","0.2.0":"2026-08-28T06:02:41.098Z","0.3.0":"2026-09-03T01:11:43.284Z","0.4.0":"2026-09-06T12:49:27.762Z"},"bugs":{"url":"https://github.com/windviki/zcode-webui/issues"},"license":"MIT","homepage":"https://github.com/windviki/zcode-webui#readme","keywords":["zcode","glm","bigmodel","zai","coding-agent","webui","code-server","browser"],"repository":{"url":"git+https://github.com/windviki/zcode-webui.git","type":"git"},"description":"Run the official ZCode desktop UI in any browser, backed by the official zcode-server runtime, with code-server integration.","maintainers":[{"name":"windviki","email":"windviki@gmail.com"}],"readme":"# zcode-webui\n\n> 语言 / Language：**中文** | [English](./README.en.md)\n\n在浏览器里完整运行官方 ZCode 桌面端界面，后端复用你机器上的官方运行时（`zcode-server` + GLM Agent）。\n它是对官方桌面端的补充：部署一次之后，手机、平板、瘦终端、任何有浏览器的设备都能随时打开同一个 ZCode，\n进行任务派发与会话推进——代码、会话和凭据始终留在你自己的服务器上。\n\n- 🖥️ **官方界面原样呈现**：聊天、任务、文件树等能力与桌面端一致；官方界面升级只需重新执行一次下载脚本\n- 🤝 **与 code-server 天然协同**：挂在 `/proxy/<port>/` 即可，共用其登录鉴权；WebSocket 被拦截时自动降级 HTTP 长轮询\n- ⏳ **任务与标签页解耦**：关闭标签页/断网不中断任务；空闲的后台会话按三重条件自动回收，运行中的永不回收\n- 🔑 **登录灵活**：内置 OAuth 登录，或从已登录的桌面端导出凭据导入；与官方客户端共用同一凭据库\n- 🔍 Ctrl+滚轮 / 双指捏合应用级缩放（50%–200%）：以捏合点为锚点平滑缩放、随手平移，\n  页面永不脱离视口（边缘保护，缩小方向逐帧直接提交，无白边）\n- 🧭 `zcode-webui setup` 一键部署：渲染层、官方运行时、配置、启动全自动\n- 📦 不打包、不修改、不分发任何官方代码；核心只有几个源文件\n\n## 快速开始\n\n> 前提：Linux x64/arm64 · Node.js ≥ 18 · `curl`、`dpkg-deb`、`tar` · 磁盘 ≥ 2GB ·\n> 能访问 `cdn-zcode.z.ai`（下载）与 `zcode.z.ai`（登录）。\n\n```bash\nnpm install -g @aixyzstudio/zcode-webui   # 需要 Node.js ≥ 18\nzcode-webui setup --yes                   # 全自动：渲染层下载 → 官方运行时安装 → 写配置 → 启动 → 健康检查\n```\n\n完成后浏览器打开 `http://<服务器>:3102/`。未登录时先访问 `/login` 完成 OAuth（服务器无法直连\n`zcode.z.ai/api/v1` 时用 `setup --oauth-proxy <代理>` 或见 [FAQ](#常见问题faq)）。\n\ngit 部署方式见[手动部署](#手动部署git-clone)；想省事也可以只跑 `zcode-webui setup` 进入交互式向导。\n\n## 与官方的关系：我们只做了中间层\n\n| 环节 | 谁来实现 |\n|---|---|\n| 界面（renderer） | 官方客户端原样，由部署者通过本项目脚本从官方 CDN 下载，**不进入本仓库、不二次分发** |\n| Agent / 模型调用 / 会话存储 | 官方运行时 `zcode-server.cjs` 与 GLM Agent，**未做任何修改** |\n| 登录认证 | 官方 CLI 的 OAuth 流程，凭据写入官方库 `~/.zcode/v2/credentials.json`（与官方客户端共用） |\n| **本项目的中间层** | 托管官方界面并注入启动配置；`window.zcode` 浏览器适配层；MessagePort ↔ WebSocket 桥；拉起官方运行时进程并转发消息 |\n\n> **免责声明**：社区项目，与智谱 / Z.ai 无隶属关系；不含任何官方代码。请遵守官方服务条款，\n> 模型调用费用按你的订阅计费。\n\n## 手动部署（git clone）\n\n```bash\ngit clone https://github.com/windviki/zcode-webui.git\ncd zcode-webui && npm install          # 运行时依赖只有 ws\n\nnpm run fetch-renderer                 # 从官方 CDN 下载安装包并提取界面\n                                       # （默认 3.9.2，可用 ZCODE_VERSION=… ZCODE_ARCH=x64 覆盖）\n\ncp config.example.json config.json     # 可选；常用字段 workspace / oauthProxy / hostProxy\n\nnpm start                              # 等价于 node src/server.mjs，默认 http://0.0.0.0:3102/\n```\n\n长期运行建议用上面的 `zcode-webui setup --systemd`，或手写系统级单元：\n\n```ini\n[Unit]\nDescription=zcode-webui\nAfter=network-online.target\n\n[Service]\nUser=你的用户名\nWorkingDirectory=/opt/zcode-webui\nExecStart=/usr/bin/node src/server.mjs\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\n```\n\n## 与 code-server 协同（推荐）\n\n以根路径模式启动（**不要设置 basePath**）：`node src/server.mjs --port 3102`。\n之后无需任何额外配置——公网入口就是 `https://<域名>/proxy/3102/`：\n\n- 资源路径、API、WebSocket、登录页都按页面 URL 自动推导；缺斜杠的 `/proxy/3102` 自动补全重定向；\n- WebSocket 不通时前端自动降级为 HTTP 长轮询桥；\n- 共用 code-server 的登录鉴权，无需 nginx。\n\n自有反代的子路径部署：`ZCODE_WEBUI_BASE_PATH=/zcode npm start`（裸 `/zcode` 会 302 补斜杠）；\nnginx 保留前缀转发即可（`proxy_pass http://127.0.0.1:3102;` 不带 URI + 常规 Upgrade 头）。\n\n## 登录与凭据（三种方式任选）\n\n**A · 直接在 WebUI 里 OAuth 登录（最简单，需要服务器能访问 zcode.z.ai）**\n打开 `<服务地址>/login` 点「开始登录」，在授权链接里完成 Z.ai OAuth，凭据自动写入服务器的\n`~/.zcode/v2/credentials.json`。\n\n**B · 从已登录的桌面端导出凭据导入（无需服务器出网）**\n在桌面电脑上打开 `<服务地址>/export-credentials.html`（纯浏览器本地运行），选择该机的\n`~/.zcode/v2/credentials.json` 并填入 platform/主目录/用户名解密，把输出 JSON 粘贴到 WebUI 的\n`/login`「导入凭据」框。\n\n**C · 服务器上本来就登录过官方 CLI / 桌面端**\n`~/.zcode` 已就绪，直接使用。\n\n## 任务生命周期（重要，30 秒读完）\n\n同一账号只有一个正在运行的宿主进程，**所有设备的页面都作为它的视图接入**：\n\n- **多设备同时实况**：任何设备打开页面即接入同一进程——历史与实时输出全部可见、持续推送；\n  换设备、多设备同时开着看，互不干扰、互不刷新；\n- **关闭标签页不结束任务**：最后一个页面离开后，进程转入后台继续执行直到完成或等待输入\n  （空闲默认 30 分钟回收；执行中/等待输入的永不回收）；\n- **注意**：若另一台设备的任务还在执行就发新指令，两个代理仍会并发操作同一批文件——\n  请等任务完成，或明确需要并行时再发；\n- **重启 zcode-webui 服务进程会中断后台任务**（与桌面端重启一致）。\n\n## 配置参考\n\n优先级：命令行参数 ≈ 环境变量 > `config.json` > 默认值。\n\n| 环境变量 / 参数 | config.json | 默认 | 说明 |\n|---|---|---|---|\n| `ZCODE_WEBUI_PORT` / `--port` | `port` | `3102` | 监听端口 |\n| `ZCODE_WEBUI_BASE_PATH` / `--base-path` | `basePath` | 空（根路径） | URL 前缀，如 `/zcode`（code-server 代理模式**不要设置**） |\n| `ZCODE_WEBUI_WORKSPACE` / `--workspace` | `workspace` | `$HOME` | 初始工作区目录 |\n| `ZCODE_WEBUI_LOCALE` | `locale` | `zh-CN` | 界面语言 |\n| `ZCODE_WEBUI_OAUTH_PROXY` / `--oauth-proxy` | `oauthProxy` | 空 | OAuth 登录用的 HTTP 代理（服务器直连 `zcode.z.ai/api/v1` 不通时） |\n| `ZCODE_WEBUI_HOST_PROXY` / `--host-proxy` | `hostProxy` | 空 | 运行时/Agent 访问云与模型 API 的 HTTP 代理（`api.z.ai`、`open.bigmodel.cn` 不通时） |\n| `ZCODE_SERVER_RUNTIME_ROOT` | `serverRoot` | `~/.zcode/server` | 官方运行时目录（通常无需修改） |\n| `ZCODE_HOME` | — | `~/.zcode` | 官方数据/凭据目录（与官方 CLI 共用） |\n| `ZCODE_WEBUI_HOME` | — | 见右 | 本服务数据目录（config、渲染层、设备标识、日志）；npm 安装默认 `~/.zcode-webui`，git 部署且项目根已有 `config.json` 或 `vendor/renderer` 时沿用项目目录 |\n| `ZCODE_VERSION` / `ZCODE_ARCH` | — | `3.9.2` / `x64` | `fetch-renderer` 的下载版本与架构 |\n| `ZCODE_WEBUI_DETACHED_TTL_MS` | — | `1800000` | 后台会话脱离超过该时长且无任务运行、无帧活动时回收；`0` = 永不回收 |\n| `ZCODE_WEBUI_FRAME_QUIET_MS` | — | `600000` | 回收条件之一：最近该时长内无 host→浏览器帧 |\n| `ZCODE_WEBUI_RUNNING_TASK_STALE_MS` | — | `7200000` | 回收的全局保险：索引里有窗口内的 running 任务时不回收任何会话 |\n| `ZCODE_WEBUI_DEBUG_RPC` | — | 关 | 设 `1` 在日志打印协议消息预览（联调用） |\n\n## 命令行参考（npm 包）\n\n| 命令 | 作用 |\n|---|---|\n| `zcode-webui setup` | 一键部署向导：目标版本解析 → 环境检查 → **官方运行时自动安装**（缺失时，来自官方组件通道）→ 凭据检查 → 渲染层下载 → 写 `config.json`（0600）→ 可选 systemd 用户单元 → 启动并等健康检查通过。`--yes` 非交互全默认并启动（配 `--no-start` 只装不启）；其它参数 `--port/--workspace/--locale/--base-path/--oauth-proxy/--host-proxy/--server-root/--version/--arch/--fetch/--no-fetch/--systemd/--no-systemd` |\n| `zcode-webui start` | 前台启动（Ctrl-C 停止；参数透传给 server.mjs） |\n| `zcode-webui stop` | 停止后台实例或 systemd 服务（前台进程请 Ctrl-C） |\n| `zcode-webui upgrade` | 一键升级官方渲染层 + 官方运行时（见下节） |\n| `zcode-webui fetch-renderer` | 仅下载/更新渲染层（`ZCODE_VERSION`/`ZCODE_ARCH` 覆盖） |\n| `zcode-webui doctor [--net]` | 就绪检查：node/curl/dpkg-deb、运行时+agent 入口、凭据、渲染层、**渲染层↔运行时版本对齐**、服务状态；`--net` 附带连通性检查 |\n| `zcode-webui status` | 打印健康 JSON（未运行返回非 0） |\n| `zcode-webui version` / `help` | 版本 / 帮助 |\n\n所有可变数据存放在数据目录（`~/.zcode-webui`，可 `ZCODE_WEBUI_HOME` 覆盖；git 部署沿用项目目录），\n包目录保持只读。\n\n### 一键升级\n\n```bash\nzcode-webui upgrade                    # 自动探测官网最新版，同步升级渲染层 + 官方运行时\nzcode-webui upgrade --yes --restart    # 非交互，并在前后自动停/启服务\n```\n\n流程：从[更新日志](https://zcode.z.ai/cn/changelog)取最新版本号 → 重提取渲染层 →\n下载官方组件清单中的运行时组件（逐一 SHA256 校验）在新目录组装后**原子替换**\n（旧目录备份为 `~/.zcode/server.bak-<版本>-<时间戳>`，仅留最近一份）。服务运行中默认询问是否先停\n（`--yes` 跳过询问但不停止）。其它参数：`--version X.Y.Z`（指定版本）、`--arch x64|arm64`、\n`--renderer-only` / `--server-only`、`--force`（同版本强制重装）、`--no-backup`。\n注意：`upgrade` 只升官方组件；zcode-webui 自身用 `npm update -g @aixyzstudio/zcode-webui` 升级。\n\n## 官方 CLI 直连（可选）\n\nWebUI 服务本身不需要 CLI 配置。若想在终端里 headless 使用官方 CLI（与 WebUI 共用凭据与会话库）：\n\n```bash\ncp cli-config.example.json ~/.zcode/cli/config.json && chmod 600 ~/.zcode/cli/config.json\n# 把 provider.bigmodel.options.apiKey 换成你的 Coding Plan API Key（或直接 zcode login 生成）\n\n~/.zcode/server/node ~/.zcode/server/agents/glm/zcode.cjs \\\n  --cwd /path/to/workspace --prompt '列出当前目录的文件' --max-turns 1\n# 续跑某个会话：加 --resume sess_xxx --prompt '继续'\n```\n\n> 密钥文件保持 0600 且在仓库之外；需要代理时设 `ZCODE_HTTP_PROXY`/`ZCODE_NO_PROXY`。\n\n## HTTP API\n\n- `GET <base>/api/health` — 服务状态（版本 / renderer / 运行时 / 登录态 / 会话数 / 回收开关）\n- `POST <base>/api/sessions/terminate` — 立即终止全部会话（含后台运行中的，慎用）\n- `POST <base>/api/login/start` · `GET /api/login/status` · `POST /api/login/cancel` — OAuth 登录流\n- `POST <base>/api/login/import` — 导入凭据 JSON（写入官方凭据库）\n- `GET <base>/api/fs/list?path=<dir>` — Web 目录选择器的目录列表\n- `POST <base>/bridge/open` · `GET /bridge/poll` · `POST /bridge/send` · `POST /bridge/close` — HTTP 长轮询桥\n- `WS <base>/ws?token=<每次启动随机>` — 前端协议桥\n\n## 安全须知\n\n- 服务默认监听 `0.0.0.0` 且**自身不做用户鉴权**（本地信任模型）：任何能访问端口的人都能以服务器上的\n  ZCode 账号身份运行 Agent。**务必放在反代/网关之后**（code-server 登录、SSO、basic auth 等），不要直接暴露公网。\n- `/api/fs/list`、`/api/login/import`、`/api/sessions/terminate` 能读文件系统/写凭据库/终止任务，同样依赖外层鉴权。\n- 凭据写入 `~/.zcode/v2/credentials.json`（0600）；`config.json` 不入库，不要提交含密钥的配置。\n- WS token 只是防误连其他 WS 服务，不是鉴权手段。\n\n## 常见问题（FAQ）\n\n**Q：关闭标签页后任务还会继续吗？**\n会，后台持续执行到完成或等待输入；重开页面自动查看进度（见「任务生命周期」）。空闲后台会话默认 30 分钟回收，\n`ZCODE_WEBUI_DETACHED_TTL_MS=0` 关闭回收，`POST /api/sessions/terminate` 立即清空。\n\n**Q：界面缩放？** Ctrl+滚轮或双指捏合（50%–200%，按浏览器记忆）；Ctrl/⌘ +/- 是浏览器整页缩放，两者并存。\n\n**Q：发送消息提示「当前没有可用的模型供应商和模型」？**\n先确认 `/login` 已登录；再跑 `zcode-webui doctor` 看渲染层与运行时的**版本对齐**是否 ok（不一致就\n`zcode-webui upgrade` 对齐）；仍报错说明是旧版本项目代码，请更新。\n\n**Q：OAuth 一直卡在「等待端点响应」？模型调用不通但登录正常？**\n前者设置 `oauthProxy`、后者设置 `hostProxy`（环境变量或 `config.json`，二者可同用），指向出口可达的 HTTP 代理后重启服务。\n\n**Q：「添加项目 → 打开文件夹」没反应？** 允许本站弹窗即可；目录选择器是内置 Web 页面。\n\n**Q：经 code-server 打开白屏？** 用带尾斜杠的 `/proxy/3102/`（会自动重定向）；WS 不通会自动降级长轮询；\n可开 `<base>/debug` 自检页看桥接状态。\n\n**Q：点击会话提示 \"ZCode agent server command is not configured\"？**\n官方运行时找不到 agent 入口。新版本启动 host 时已自动注入定位环境变量，出现该报错先跑\n`zcode-webui doctor`（看 `agent server` 是否 ok），然后**重启服务**让新代码生效；自定义路径可用\n`ZCODE_AGENT_SERVER_COMMAND` / `ZCODE_AGENT_SERVER_ARGS_JSON` 覆盖。\n\n**Q：官方界面怎么升级？** 直接 `zcode-webui upgrade`（见「一键升级」）。\n\n**Q：切到其他 App 再回来，页面重连/要求手动重连？**\n这是手机浏览器在后台冻结页面并回收网络连接所致（并非服务端超时）。新版对此透明：后台掉线**不再刷新\n页面**，恢复时通过热重连直接接管同一个运行中的宿主——离线期间任务产生的输出会在恢复瞬间补投，\n全程无感、无需任何点击。页面回前台即自动恢复；仅当宿主进程本身退出（如服务重启）才需要一次自动\n刷新。服务端另加了 30 秒 ping/pong 保活，僵死连接会被及时清理、宿主干净转入后台。\n\n**Q：服务器休眠/断网后，进行中的任务停了？**\n分两种情况：\n\n- **其实还在跑（常见）**：任何设备重新打开页面都会作为视图接入同一宿主——**实时进度无缝续看**，\n  且多台设备可同时观看、互不刷新。只有「同时发任务指令」才可能双代理并发，请避免。\n- **真的断了**：挂起/断网掐断流式连接会让该回合以失败告终（服务日志可见 `process stall of ~Ns`）。\n  可用官方 CLI 无头续跑：\n  `~/.zcode/server/node ~/.zcode/server/agents/glm/zcode.cjs --cwd <工作区> --resume <会话ID> --prompt '继续'`；\n  刷新页面即加载最新落库状态。长任务期间请避免让服务器休眠。\n\n**Q：定时/闲时任务能跑吗？** 该调度器属官方桌面端专属；可在服务器上用系统 cron 调官方 CLI 的\n`--prompt/--resume` 实现，按订阅规则计费。\n\n## 测试\n\n```bash\nnpm run smoke                            # 静态服务 + base path + WS/HTTP 双桥全链路冒烟\nbash scripts/docker/verify.sh            # Docker 真机全链路：npm 包 → 自动安装 → 服务 → 冒烟 → 真实模型调用\nZCODE_VERIFY_FRESH_RUNTIME=1 bash scripts/docker/verify.sh   # 更严苛：容器里只有凭据、无官方运行时，\n                                                             # 验证 setup 从零自动安装（CDN 组件下载 + SHA256 校验）\n```\n\nDocker 验证会把本机 `~/.zcode` 复制进临时沙箱注入容器，用完即删；镜像层与仓库不含任何凭据。\n可用 `ZCODE_VERIFY_SOURCE/PROXY/NETWORK/KEEP/SKIP_FETCH` 覆盖默认行为。`scripts/dev/` 下另有一组\nPlaywright 端到端脚本（真实登录态驱动官方界面的回归），可用 `ZCODE_WEBUI_TEST_URL/TEST_DIR` 指向自己的服务。\n\n## 已知限制\n\n- 不支持 SSH/WSL/Docker 远程工作区创建（服务本身就运行在你的工作区机器上）\n- 手机 Remote Control、系统托盘、自动更新等桌面专属通道不可用（Browser Use 可走服务器无头 Chrome）\n- 定时/闲时任务依赖桌面端调度器（见 FAQ）\n- 服务进程重启会中断后台任务；HTTP 长轮询模式下重开页面不能无缝接管会话（结果仍可在任务面板看到）\n- 官方界面随版本演进，个别新 UI 可能暂时兼容性问题；渲染层与运行时务必同版本\n\n## 目录结构\n\n```\nsrc/server.mjs             HTTP 静态服务 + base path + WS 桥 + 登录 API + 会话管理\nsrc/cli.mjs                zcode-webui 命令行（setup / start / stop / upgrade / doctor / status）\nsrc/dirs.mjs               数据目录解析（ZCODE_WEBUI_HOME / 仓库模式）\nsrc/frame.mjs              stdio 帧编解码（与官方运行时互通）\nsrc/host.mjs               官方运行时进程拉起与握手\nsrc/upgrade.mjs            版本探测 + 渲染层/官方运行时组件下载校验与原子替换\nsrc/login.mjs              官方 CLI OAuth 登录子进程管理\nsrc/rpclog.mjs             诊断日志（DEBUG_RPC 时使用）\nweb/bootstrap.js           浏览器侧：URL 参数、MessagePort↔WebSocket 桥、长轮询降级\nweb/zcode-bridge.js        window.zcode 浏览器适配层\nweb/{login,picker,debug}.html 等   登录页 / 目录选择器 / 自检页 / 凭据导出工具\nconfig.example.json        服务配置模板（脱敏）\ncli-config.example.json    官方 CLI 模型配置模板（脱敏）\nscripts/fetch-renderer.sh  从官方 CDN 下载客户端并提取渲染层（vendor/renderer，不入库）\nscripts/smoke-test.mjs     冒烟测试\nscripts/docker/            Docker 真机全链路验证（verify.sh + container-verify.sh）\nscripts/dev/*.mjs          Playwright 端到端联调脚本\n```\n\n## 许可证与声明\n\n- 代码以 [MIT](./LICENSE) 开源；\n- 官方 ZCode 名称、商标与客户端版权归其权利方所有；本项目不包含、不分发任何官方客户端文件；\n- 参考：[ZCode 官方文档](https://zcode.z.ai/cn/docs) · [智谱开放平台](https://open.bigmodel.cn) ·\n  [GLM Coding Plan](https://docs.bigmodel.cn/cn/coding-plan/overview)。\n","readmeFilename":"README.md"}