diff --git a/development-environment-startup-manual.md b/development-environment-startup-manual.md new file mode 100644 index 00000000..3fc5f8e2 --- /dev/null +++ b/development-environment-startup-manual.md @@ -0,0 +1,1821 @@ +# Qiming 开发环境启动手册 + +本文档从零重新整理。当前先确认端口规划,后续章节按确认结果继续补充。 + +## 1. 端口规划 + +### 1.1 规划原则 + +Qiming 开发环境按“本机开发 + 服务器基础服务/沙箱服务”的方式规划。 + +本机 Windows 主要运行: + +- `qiming` 前端 +- `qiming-backend` 后端 +- `qiming-file-server` 文件服务 +- `mcp-proxy` +- `run_code_rmcp` +- `qimingclaw`、`qimingcode` 等按需开发工具 + +服务器主要运行: + +- Milvus +- Elasticsearch +- rcoder +- rcoder 相关代理、可观测组件 + +端口规划尽量满足以下约束: + +- 主项目服务统一使用 `18xxx`。 +- 本机 MySQL、Redis 保留当前已确认端口:MySQL `3308`,Redis `16379`。 +- 避开常见默认端口冲突,例如 `3000`、`8080`、`8088`、`9091`。 +- Docker 服务的宿主机端口使用显式端口,不依赖镜像内部默认端口。 +- `stdio` 类型组件不占用 TCP 端口,不写入端口表。 + +### 1.2 本机端口规划 + +| 端口 | 服务 | 运行位置 | 必须启动 | 当前来源 | 说明 | +| --- | --- | --- | --- | --- | --- | +| `18000` | `qiming` 前端 | 本机 | 是 | `qiming/.env` | Umi/Max 前端访问入口 | +| `18081` | `qiming-backend` | 本机 | 是 | `application-dev.yml` | 后端 API,前端 `/api/` 代理到这里 | +| `3308` | MySQL | 本机 | 是 | `application-dev.yml` | 当前开发库端口 | +| `16379` | Redis | 本机 | 是 | `application-dev.yml` | 当前开发 Redis 端口 | +| `16000` | `qiming-file-server` | 本机 | 是 | `qiming-file-server/src/env.development` | 文件服务,后端 `BUILD_SERVER_URL` 指向这里 | +| `18020` | `mcp-proxy` HTTP 服务 | 本机 | 是 | 后端 `CODE_EXECUTE_URL` / `MCP_PROXY_URL` | 建议通过环境变量固定,避免默认 `8080` | +| `18082` | `custom-page.http-proxy` | 本机 | 按需 | `application-dev.yml` | 自定义页面代理端口 | +| `18085` | `computer.proxy` | 本机 | 按需 | `application-dev.yml` | Computer Agent 代理端口 | +| `18086` | `model-api-proxy` | 本机 | 按需 | `application-dev.yml` | 后端本机模型代理端口;服务器 rcoder 不使用该端口 | +| `11076` | `reverse.server.outer` | 本机或服务器 | 按需 | `application-dev.yml` | 反向连接外部端口 | +| `30000-40000` | `reverse.server.inner` | 本机或服务器 | 按需 | `application-dev.yml` | 反向代理内部端口池 | +| `60173` | `qimingclaw` Vite | 本机 | 按需 | `qimingclaw/crates/agent-electron-client/vite.config.ts` | Electron 开发时等待该端口 | +| `60008` | `agent-gui-server` HTTP MCP | 本机 | 按需 | `guiAgentServer.ts` 注释和默认常量 | qimingclaw 内置 GUI MCP 服务默认端口 | +| `18030` | `qimingcode` OpenCode API | 本机 | 按需 | 规划端口 | 源码默认 `4096`,启动时通过 `--port 18030` 固定 | +| `18031` | `qimingcode` Web UI | 本机 | 按需 | 规划端口 | 源码默认 `3000`,启动时通过 Vite `--port 18031` 固定 | + +### 1.3 服务器端口规划 + +| 端口 | 服务 | 运行位置 | 必须启动 | 当前来源 | 说明 | +| --- | --- | --- | --- | --- | --- | +| `19530` | Milvus | 服务器 | 是 | Milvus 默认/现有环境 | 后端 `MILVUS_URI` 指向此端口 | +| `9091` | Milvus health/metrics | 服务器 | 是 | 现有 Milvus compose | 已被 Milvus 占用,不再给 Prometheus 使用 | +| `9000` | MinIO API | 服务器 | 是,Milvus 依赖 | Milvus compose | Milvus 对象存储依赖 | +| `9001` | MinIO Console | 服务器 | 按需 | Milvus compose | MinIO 管理控制台 | +| `19200` | Elasticsearch | 服务器 | 是 | Elasticsearch compose | 宿主机 `19200` 映射容器 `9200` | +| `18087` | rcoder API | 服务器 | 完整体验建议启动 | 规划端口 | 替代 rcoder 默认 `8087/8090` | +| `18088` | rcoder Pingora/Docker proxy | 服务器 | 完整体验建议启动 | 规划端口 | 后端 `DOCKER_PROXY_URL` 指向这里 | +| `18199` | rcoder Web/noVNC 入口 | 服务器 | 按需 | 规划端口 | 替代 compose 默认宿主机 `8199` | +| `19090` | rcoder Prometheus | 服务器 | 按需 | 规划端口 | 替代 compose 默认宿主机 `9091`,避免和 Milvus 冲突 | +| `13000` | rcoder Grafana | 服务器 | 按需 | 规划端口 | 替代 compose 默认宿主机 `3000`,避免和前端工具冲突 | +| `14040` | rcoder Pyroscope | 服务器 | 按需 | 规划端口 | 替代 compose 默认宿主机 `4040`,统一到 5 位端口 | + +说明:`rcoder` 镜像会显示容器内部 `8086/tcp`,这是动态 `agent_runner` 子容器使用的内部 HTTP 端口,不映射为服务器固定入口。服务器对外固定使用 `18087` 访问 rcoder 主 API,使用 `18088` 访问 Pingora 代理。 + +### 1.4 不单独规划 TCP 端口的组件 + +| 组件 | 原因 | +| --- | --- | +| `run_code_rmcp` / `script_runner` | 本身是命令行/stdio MCP 能力,不直接监听 HTTP 端口 | +| `claude-code-acp-ts` | ACP stdio 服务,由上层客户端拉起,不直接监听 HTTP 端口 | +| `qiming-mcp-stdio-proxy` stdio 模式 | stdio 模式不占用 TCP 端口 | +| `lanproxy-go-client` | 取决于服务端分配和配置,不在本地固定规划 | +| `noVNC` | 当前作为 rcoder/Computer Agent 能力的一部分,不单独作为主服务规划 | +| `qiming-mobile` | 当前 `package.json` 没有本地 dev server 脚本,先不固定端口 | + +### 1.5 需要调整或特别注意的默认端口 + +| 文件或组件 | 当前默认 | 规划处理 | +| --- | --- | --- | +| `mcp-proxy/config.yml` | `8080` | 启动时使用 `MCP_PROXY_PORT=18020`,或后续改配置 | +| `qimingcode/packages/opencode` API | `4096` | 启动时使用 `--port 18030`,否则 Web UI 会连错端口 | +| `qimingcode/packages/app/vite.config.ts` | `3000` | 启动时使用 `--port 18031`,并设置 `VITE_OPENCODE_SERVER_PORT=18030` | +| `rcoder/docker/docker-compose.yml` Grafana | `3000:3000` | 建议改为 `13000:3000` | +| `rcoder/docker/docker-compose.yml` Prometheus | `9091:9090` | 必须改为 `19090:9090`,因为 `9091` 已被 Milvus 使用 | +| `rcoder/docker/docker-compose.yml` Pyroscope | `4040:4040` | 建议改为 `14040:4040` | +| `rcoder/docker/docker-compose.yml` Pingora | `8088:8088` | 建议改为 `18088:8088` | +| `rcoder/docker/docker-compose.yml` Web/noVNC | `8199:80` | 建议改为 `18199:80` | +| `rcoder` 镜像内部端口 | `8086/tcp` | 不映射;这是 agent_runner 内部端口,不作为服务器访问入口 | +| `qiming-backend` sample 配置 | MySQL `3306`、Redis `6379`、ES `9200` | 不直接使用 sample;开发配置以 `application-dev.yml` 为准 | + +### 1.6 后端连接目标 + +`qiming-backend` 在开发环境中应按下表连接其他服务: + +| 后端配置项 | 推荐值 | +| --- | --- | +| `server.port` | `18081` | +| `spring.datasource.dynamic.datasource.master.url` | `jdbc:mysql://localhost:3308/agent_platform...` | +| `spring.data.redis.port` | `16379` | +| `milvus.uri` | `http://服务器IP:19530/` | +| `search.elasticsearch.url` | `http://服务器IP:19200` | +| `custom-page.build-server.base-url` | `http://localhost:16000/api` | +| `code.execute.url` | `http://localhost:18020/api/run_code_with_log` | +| `mcp.proxy-base-url` | `http://localhost:18020` | +| `custom-page.ai-agent.base-url` | `http://服务器IP:18087` | +| `custom-page.docker-proxy.base-url` | `http://服务器IP:18088` | +| `model-api-proxy.base-api-url` | `http://服务器IP:18087` | + +### 1.7 端口确认命令 + +Windows 本机执行: + +```powershell +Get-NetTCPConnection -LocalPort 18000,18081,3308,16379,16000,18020,18082,18085,18086,11076,60173,60008,18030,18031 -ErrorAction SilentlyContinue | + Select-Object LocalAddress,LocalPort,State,OwningProcess | + Sort-Object LocalPort +``` + +Linux 服务器执行: + +```bash +ss -lntp | grep -E '19530|9091|9000|9001|19200|18087|18088|18199|19090|13000|14040' || true +docker ps --format 'table {{.Names}}\t{{.Ports}}' +``` + +服务器 rcoder 相关服务验证: + +```bash +curl -f http://127.0.0.1:18087/health +curl -f http://127.0.0.1:18088/health +curl -f http://127.0.0.1:19090/-/healthy +curl -f http://127.0.0.1:13000/api/health + +# Pyroscope 不使用 /health 验证;/health 返回 404 属于正常现象。 +# 确认 14040 端口监听,并确认 HTTP 服务有响应即可。 +ss -lntp | grep 14040 +curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:14040 +``` + +### 1.8 当前确认结论 + +第一阶段端口规划建议确认如下: + +- MySQL 固定 `3308`。 +- Redis 固定 `16379`。 +- `qiming` 固定 `18000`。 +- `qiming-backend` 固定 `18081`。 +- `qiming-file-server` 固定 `16000`。 +- `mcp-proxy` 固定 `18020`。 +- Milvus 固定 `19530`,其 `9091` 端口保留给 Milvus,不给 rcoder Prometheus。 +- Elasticsearch 固定 `19200`。 +- rcoder 相关服务统一调整到 `18087`、`18088`、`18199`、`19090`、`13000`、`14040`。 +- rcoder 不使用 `18086` 作为服务器外部入口;后端连接 rcoder 主服务用 `18087`,连接 Pingora 代理用 `18088`。 + +## 2. 服务器基础服务安装 + +本章在服务器执行,示例服务器目录统一放在: + +```bash +mkdir -p ~/nuwax-dev +cd ~/nuwax-dev +``` + +服务器需要先具备 Docker 和 Docker Compose v2: + +```bash +docker version +docker compose version +``` + +如果 `docker compose version` 正常,后续统一使用 `docker compose`,不要使用旧命令 `docker-compose`。 + +### 2.1 Milvus 安装、启动、验证 + +Milvus 用于向量检索。当前开发环境使用 standalone 模式,同时启动 `etcd` 和 `minio`。 + +#### 2.1.1 创建目录 + +```bash +mkdir -p ~/nuwax-dev/milvus +cd ~/nuwax-dev/milvus +mkdir -p volumes/etcd volumes/minio volumes/milvus +``` + +#### 2.1.2 创建 `docker-compose.yml` + +文件名固定为: + +```text +~/nuwax-dev/milvus/docker-compose.yml +``` + +内容: + +```yaml +services: + etcd: + container_name: milvus-etcd + image: quay.io/coreos/etcd:v3.5.16 + environment: + - ETCD_AUTO_COMPACTION_MODE=revision + - ETCD_AUTO_COMPACTION_RETENTION=1000 + - ETCD_QUOTA_BACKEND_BYTES=4294967296 + - ETCD_SNAPSHOT_COUNT=50000 + volumes: + - ./volumes/etcd:/etcd + command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd + healthcheck: + test: ["CMD", "etcdctl", "endpoint", "health"] + interval: 30s + timeout: 20s + retries: 3 + + minio: + container_name: milvus-minio + image: minio/minio:RELEASE.2023-03-20T20-16-18Z + environment: + MINIO_ACCESS_KEY: minioadmin + MINIO_SECRET_KEY: minioadmin + ports: + - "9000:9000" + - "9001:9001" + volumes: + - ./volumes/minio:/minio_data + command: minio server /minio_data --console-address ":9001" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 30s + timeout: 20s + retries: 3 + + standalone: + container_name: milvus-standalone + image: milvusdb/milvus:v2.5.4 + command: ["milvus", "run", "standalone"] + security_opt: + - seccomp:unconfined + environment: + ETCD_ENDPOINTS: etcd:2379 + MINIO_ADDRESS: minio:9000 + volumes: + - ./volumes/milvus:/var/lib/milvus + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"] + interval: 30s + start_period: 90s + timeout: 20s + retries: 3 + ports: + - "19530:19530" + - "9091:9091" + depends_on: + - etcd + - minio + +networks: + default: + name: milvus +``` + +#### 2.1.3 启动 + +```bash +cd ~/nuwax-dev/milvus +docker compose up -d +``` + +#### 2.1.4 验证 + +```bash +docker compose ps +docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' | grep -E 'milvus|etcd|minio' +ss -lntp | grep -E '19530|9091|9000|9001' +curl -f http://127.0.0.1:9091/healthz +``` + +预期: + +- `milvus-standalone` 状态为 `healthy`。 +- `19530`、`9091`、`9000`、`9001` 均已监听。 +- `9091` 已分配给 Milvus,不再给 rcoder Prometheus 使用。 + +### 2.2 Elasticsearch 安装、启动、验证 + +Elasticsearch 用于日志检索、模型代理日志等能力。开发环境关闭安全认证,端口统一映射为 `19200`。 + +#### 2.2.1 创建目录 + +```bash +mkdir -p ~/nuwax-dev/elasticsearch +cd ~/nuwax-dev/elasticsearch +mkdir -p data/elasticsearch +``` + +Elasticsearch 容器默认用户需要写入 data 目录。服务器上执行: + +```bash +chown -R 1000:0 ./data/elasticsearch +chmod -R g+rwx ./data/elasticsearch +``` + +如果不处理权限,可能出现: + +```text +failed to obtain node locks +AccessDeniedException: /usr/share/elasticsearch/data/node.lock +``` + +#### 2.2.2 创建 `docker-compose.yml` + +文件名固定为: + +```text +~/nuwax-dev/elasticsearch/docker-compose.yml +``` + +内容: + +```yaml +services: + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:9.2.1 + container_name: nuwax-elasticsearch + restart: always + environment: + discovery.type: single-node + xpack.security.enabled: "false" + ES_JAVA_OPTS: "-Xms1g -Xmx1g" + ports: + - "19200:9200" + volumes: + - ./data/elasticsearch:/usr/share/elasticsearch/data +``` + +#### 2.2.3 启动 + +```bash +cd ~/nuwax-dev/elasticsearch +docker compose up -d +``` + +#### 2.2.4 验证 + +Elasticsearch 启动需要等待一会儿: + +```bash +docker compose ps +docker logs nuwax-elasticsearch --tail 100 +ss -lntp | grep 19200 +curl -f http://127.0.0.1:19200 +curl -f http://127.0.0.1:19200/_cluster/health?pretty +``` + +预期 `curl http://127.0.0.1:19200` 返回集群信息,`cluster_name` 通常为 `docker-cluster`。 + +如果 `docker compose ps` 显示容器刚启动但 `curl` 返回: + +```text +Recv failure: Connection reset by peer +``` + +先看日志: + +```bash +docker logs nuwax-elasticsearch --tail 200 +``` + +常见原因是 data 目录权限错误,按 2.2.1 重新授权后重启: + +```bash +cd ~/nuwax-dev/elasticsearch +docker compose down +chown -R 1000:0 ./data/elasticsearch +chmod -R g+rwx ./data/elasticsearch +docker compose up -d +``` + +后端开发配置: + +```yaml +search: + elasticsearch: + url: http://服务器IP:19200 + username: + password: + api_key: +``` + +当前开发环境关闭了 ES 安全认证,所以 `username`、`password`、`api_key` 留空。 + +### 2.3 rcoder 安装、启动、验证 + +rcoder 用于沙箱、Computer Agent、页面预览代理、动态容器管理等完整体验能力。开发环境建议部署在服务器 Docker 中。 + +#### 2.3.1 准备源码和目录 + +如果服务器已经有源码: + +```bash +cd ~/nvw/rcoder +``` + +如果服务器没有源码,先拉取: + +```bash +mkdir -p ~/nvw +cd ~/nvw +git clone https://github.com/nuwax-ai/rcoder.git +cd rcoder +``` + +确认 Docker 可用: + +```bash +docker ps +ls -l /var/run/docker.sock +``` + +#### 2.3.2 安装构建依赖 + +如果需要在服务器本地构建镜像,先安装基础工具: + +```bash +apt update +apt install -y build-essential pkg-config libssl-dev cmake protobuf-compiler make curl git +``` + +如果执行构建时报: + +```text +is `cmake` not installed? +``` + +说明缺少 `cmake`,执行: + +```bash +apt install -y cmake +``` + +如果 `make dev-build` 报: + +```text +skopeo: No such file or directory +``` + +安装: + +```bash +apt install -y skopeo +``` + +#### 2.3.3 修改 rcoder 端口 + +rcoder 原始 compose 里有 `8088`、`8199`、`9091`、`3000` 等默认端口,会和当前开发环境冲突。按当前规划执行下面命令修改。 + +```bash +cd ~/nvw/rcoder + +cp docker/docker-compose.yml docker/docker-compose.yml.bak.$(date +%Y%m%d%H%M%S) +cp docker/config.yml docker/config.yml.bak.$(date +%Y%m%d%H%M%S) +cp docker/start-rcoder.sh docker/start-rcoder.sh.bak.$(date +%Y%m%d%H%M%S) + +python3 - <<'PY' +from pathlib import Path +import re + +compose = Path("docker/docker-compose.yml") +s = compose.read_text() + +s = re.sub( + r'(\n\s+ports:\n)(?:\s+- .*\n)+(?=\s+environment:)', + '\n ports:\n' + ' - "18087:18087" # rcoder 主服务 API\n' + ' - "18088:8088" # Pingora 反向代理端口\n' + ' - "60001:60000" # 保留端口\n' + ' - "18199:80" # Web/noVNC 入口\n', + s, + count=1, +) + +s = re.sub( + r'RCODER_PORT=\$\{RCODER_PORT:-\d+\}', + 'RCODER_PORT=18087', + s, +) + +s = re.sub( + r'http://localhost:\$\{RCODER_PORT:-\d+\}/health', + 'http://localhost:18087/health', + s, +) + +s = s.replace('"4040:4040"', '"14040:4040"') +s = s.replace('"9091:9090"', '"19090:9090"') +s = s.replace('"3000:3000"', '"13000:3000"') + +compose.write_text(s) + +config = Path("docker/config.yml") +c = config.read_text() +c = re.sub(r'(?m)^port:\s*\d+', 'port: 18087', c, count=1) +c = re.sub(r'(?m)^(\s*)listen_port:\s*\d+', r'\1listen_port: 8088', c, count=1) +c = re.sub(r'(?m)^(\s*)default_backend_port:\s*\d+', r'\1default_backend_port: 18087', c, count=1) +config.write_text(c) + +start = Path("docker/start-rcoder.sh") +t = start.read_text() +t = re.sub(r'RCODER_PORT=\$\{RCODER_PORT:-\d+\}', 'RCODER_PORT=${RCODER_PORT:-18087}', t) +start.write_text(t) +PY +``` + +说明: + +- `18087`:rcoder 主服务 API。 +- `18088`:Pingora 代理,对外给后端 `DOCKER_PROXY_URL` 使用。 +- `18199`:Web/noVNC 入口。 +- `19090`:Prometheus,避免占用 Milvus 的 `9091`。 +- `13000`:Grafana,避免占用常见前端端口 `3000`。 +- `14040`:Pyroscope。 +- 容器内部显示 `8086/tcp` 是正常现象,不映射到宿主机;它是动态 `agent_runner` 子容器的内部服务端口。 + +#### 2.3.4 构建镜像 + +如果镜像已存在并且架构正确,可以跳过构建。先检查: + +```bash +docker image inspect nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/master-rcoder:latest \ + --format 'image_os={{.Os}} image_arch={{.Architecture}} entrypoint={{json .Config.Entrypoint}}' +``` + +服务器是 `x86_64` 时,镜像应为: + +```text +image_os=linux image_arch=amd64 +``` + +如果显示 `arm64`,启动会报: + +```text +exec /usr/local/bin/docker-entrypoint.sh: exec format error +``` + +需要重新构建 amd64 镜像: + +```bash +cd ~/nvw/rcoder +make dev-build +``` + +#### 2.3.5 启动 + +```bash +cd ~/nvw/rcoder +docker compose -f docker/docker-compose.yml up -d --force-recreate rcoder prometheus grafana pyroscope +``` + +#### 2.3.6 验证 + +```bash +docker compose -f docker/docker-compose.yml ps +docker logs rcoder-rcoder-1 --tail 100 +ss -lntp | grep -E '18087|18088|18199|60001|19090|13000|14040' || true +``` + +主服务验证: + +```bash +curl -f http://127.0.0.1:18087/health +curl -f http://127.0.0.1:18088/health +``` + +可观测服务验证: + +```bash +curl -f http://127.0.0.1:19090/-/healthy +curl -f http://127.0.0.1:13000/api/health + +# Pyroscope 不使用 /health 验证;/health 返回 404 属于正常现象。 +ss -lntp | grep 14040 +curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:14040 +``` + +已经验证通过的典型结果: + +```text +18087 rcoder 主服务: {"status":"healthy","service":"rcoder-ai-service"} +18088 rcoder Pingora: {"status":"healthy","service":"rcoder-ai-service"} +19090 Prometheus: Prometheus Server is Healthy. +13000 Grafana: {"database":"ok", ...} +14040 Pyroscope: 端口监听且 HTTP 服务有响应 +``` + +#### 2.3.7 控制台入口 + +```text +rcoder API 文档: http://服务器IP:18087/api/docs +rcoder 健康检查: http://服务器IP:18087/health +rcoder Pingora: http://服务器IP:18088 +rcoder Web/noVNC: http://服务器IP:18199 +Grafana: http://服务器IP:13000 +Prometheus: http://服务器IP:19090 +Pyroscope: http://服务器IP:14040 +``` + +Grafana 默认账号密码: + +```text +admin / admin +``` + +#### 2.3.8 后端连接配置 + +`qiming-backend` 连接 rcoder 时使用: + +```yaml +custom-page: + ai-agent: + base-url: http://服务器IP:18087 + docker-proxy: + enable: true + base-url: http://服务器IP:18088 + +model-api-proxy: + base-api-url: http://服务器IP:18087 +``` + +不要把服务器 rcoder 配成 `18086`。`18086` 当前仅作为本机 `model-api-proxy` 规划端口,不是服务器 rcoder 外部入口。 + +## 3. mcp-proxy 安装、启动、验证 + +`mcp-proxy` 在本地启动,固定使用 `18020` 端口。`qiming-backend` 会通过它访问代码执行和 MCP 代理能力: + +```yaml +code: + execute: + url: http://localhost:18020/api/run_code_with_log + +mcp: + proxy-base-url: http://localhost:18020 +``` + +因此启动顺序上,建议先启动 `mcp-proxy`,再启动 `qiming-backend`。 + +### 3.1 前置要求 + +本机需要先安装 Rust 工具链,并确认 `cargo` 可用: + +```powershell +rustc --version +cargo --version +``` + +如果 PowerShell 找不到 `cargo`,先临时补充 PATH: + +```powershell +$env:Path += ";$env:USERPROFILE\.cargo\bin" +cargo --version +``` + +### 3.2 安装 + +在本机 PowerShell 执行: + +```powershell +cd D:\work\workspace\feitian-base\nvw\mcp-proxy +cargo install --path .\mcp-proxy --force +``` + +说明: + +- `--path .\mcp-proxy` 表示安装 workspace 里的 `mcp-proxy` 二进制。 +- `--force` 用于覆盖旧版本;如果不加,可能出现 `binary mcp-proxy.exe already exists in destination`。 +- 安装完成后,二进制通常位于 `C:\Users\<用户名>\.cargo\bin\mcp-proxy.exe`。 + +安装验证: + +```powershell +where.exe mcp-proxy +mcp-proxy --help +``` + +如果 `where.exe mcp-proxy` 找不到,先执行: + +```powershell +$env:Path += ";$env:USERPROFILE\.cargo\bin" +where.exe mcp-proxy +``` + +### 3.3 启动 + +打开一个新的 PowerShell 窗口,专门用于运行 `mcp-proxy`: + +```powershell +cd D:\work\workspace\feitian-base\nvw\mcp-proxy + +$env:MCP_PROXY_PORT = "18020" +$env:MCP_PROXY_LOG_LEVEL = "info" +$env:MCP_PROXY_LOG_DIR = "D:\work\workspace\feitian-base\nvw\.dev\logs\mcp-proxy" + +mcp-proxy +``` + +看到类似以下信息,表示已按 `18020` 端口启动: + +```text +MCP_PROXY_PORT override detected: 18020 +Listening on 0.0.0.0:18020 +Health endpoint: /health +MCP list endpoint: /mcp/list +``` + +不要关闭这个 PowerShell 窗口;关闭窗口后 `mcp-proxy` 也会停止。 + +### 3.4 验证 + +另开一个 PowerShell 窗口执行: + +```powershell +Test-NetConnection localhost -Port 18020 +Invoke-WebRequest http://localhost:18020/health +Invoke-WebRequest http://localhost:18020/mcp/list +``` + +期望结果: + +```text +TcpTestSucceeded : True +/health 返回 health +/mcp/list 可以返回 HTTP 响应 +``` + +也可以使用 curl 验证: + +```powershell +curl.exe -f http://localhost:18020/health +curl.exe http://localhost:18020/mcp/list +``` + +### 3.5 后端联通检查 + +确认 `qiming-backend` 的开发配置指向本机 `mcp-proxy`: + +```yaml +code: + execute: + url: ${CODE_EXECUTE_URL:http://localhost:18020/api/run_code_with_log} + +mcp: + proxy-base-url: ${MCP_PROXY_URL:http://localhost:18020} +``` + +如果后端启动后调用代码执行或 MCP 相关接口失败,优先检查: + +```powershell +Test-NetConnection localhost -Port 18020 +Invoke-WebRequest http://localhost:18020/health +``` + +### 3.6 常见问题 + +#### 3.6.1 端口被占用 + +现象: + +```text +Address already in use +``` + +检查占用: + +```powershell +netstat -ano | findstr :18020 +``` + +处理方式: + +- 优先停止占用 `18020` 的旧 `mcp-proxy` 进程。 +- 不建议临时换端口;如果换端口,`qiming-backend` 的 `CODE_EXECUTE_URL` 和 `MCP_PROXY_URL` 也必须同步修改。 + +#### 3.6.2 VS Code 终端找不到 mcp-proxy + +命令行可以找到,但 VS Code 找不到时,通常是 VS Code 启动时没有加载最新 PATH。 + +处理方式: + +```powershell +$env:Path += ";$env:USERPROFILE\.cargo\bin" +where.exe mcp-proxy +``` + +如果仍然找不到,重启 VS Code 后再打开终端。 + +#### 3.6.3 默认端口不是 18020 + +`mcp-proxy/config.yml` 默认端口可能是 `8080`。本开发环境统一固定为 `18020`,启动时必须设置: + +```powershell +$env:MCP_PROXY_PORT = "18020" +mcp-proxy +``` + +以后如果改成配置文件固定,也要确保最终监听端口仍为 `18020`。 + +## 4. run_code_rmcp 安装、启动、验证 + +`run_code_rmcp` 是本地代码执行运行时,用于执行 JavaScript、TypeScript、Python 代码。 + +它包含两个入口: + +| 命令 | 用途 | 是否常驻 | 说明 | +|---|---|---|---| +| `run_code_rmcp` | 命令行代码执行器 | 否 | 用于直接验证 JS/Python/TS 执行能力 | +| `script_runner` | MCP stdio 服务 | 是 | 通过 MCP stdio 协议等待客户端调用,不监听 HTTP 端口 | + +本开发环境里,HTTP 入口仍由 `mcp-proxy` 提供,端口是 `18020`;`run_code_rmcp` 本身不占用端口。 + +### 4.1 前置要求 + +确认 Rust、Deno、uv 都可用: + +```powershell +rustc --version +cargo --version +deno --version +uv --version +``` + +如果 PowerShell 或 VS Code 终端找不到命令,先补充常见 PATH: + +```powershell +$env:Path += ";$env:USERPROFILE\.cargo\bin" +$env:Path += ";$env:USERPROFILE\.deno\bin" +$env:Path += ";$env:USERPROFILE\.local\bin" + +rustc --version +cargo --version +deno --version +uv --version +``` + +如果直接打开系统 PowerShell 可以找到,但 VS Code 找不到,重启 VS Code 后再打开终端。 + +### 4.2 安装 + +在本机 PowerShell 执行: + +```powershell +cd D:\work\workspace\feitian-base\nvw\run_code_rmcp + +cargo install --path . --features mcp --force +cargo install --path . --bin script_runner --features mcp --force +``` + +说明: + +- 第一条安装 `run_code_rmcp.exe`。 +- 第二条安装 `script_runner.exe`。 +- `--features mcp` 用于启用 MCP 相关能力。 +- `--force` 用于覆盖旧版本。 + +安装验证: + +```powershell +where.exe run_code_rmcp +where.exe script_runner +run_code_rmcp --help +script_runner --help +``` + +### 4.3 直接执行验证 + +进入项目目录: + +```powershell +cd D:\work\workspace\feitian-base\nvw\run_code_rmcp +``` + +验证 JavaScript: + +```powershell +run_code_rmcp --show-logs js -c "function handler(){ console.log('js ok'); return 'hello nuwax'; }" +``` + +期望看到: + +```text +js ok +Result: "hello nuwax" +``` + +验证 Python: + +```powershell +run_code_rmcp --show-logs python -c "def handler(args=None): print('python ok'); return 'hello python'" +``` + +期望看到: + +```text +python ok +Result: "hello python" +``` + +如果执行 JS 失败,优先检查: + +```powershell +deno --version +``` + +如果执行 Python 失败,优先检查: + +```powershell +uv --version +``` + +### 4.4 启动 MCP stdio 服务 + +`script_runner` 是 MCP stdio 服务,不监听端口。手动启动后,它会等待 MCP 客户端通过标准输入输出发送协议消息。 + +启动命令: + +```powershell +cd D:\work\workspace\feitian-base\nvw\run_code_rmcp +script_runner --verbose +``` + +看到进程停在当前窗口是正常现象,表示它正在等待 MCP 客户端连接。不要用浏览器或 `curl` 验证它,因为它不是 HTTP 服务。 + +如果只是验证本地代码执行能力,优先使用 `4.3` 的 `run_code_rmcp --show-logs ...` 两条命令。 + +### 4.5 与 mcp-proxy 的关系 + +当前后端配置访问的是: + +```yaml +code: + execute: + url: http://localhost:18020/api/run_code_with_log + +mcp: + proxy-base-url: http://localhost:18020 +``` + +也就是说: + +```text +qiming-backend -> mcp-proxy:18020 -> 代码执行/MCP 能力 +``` + +开发启动时建议顺序: + +```text +1. 确认 run_code_rmcp / script_runner 已安装并验证通过 +2. 启动 mcp-proxy,固定端口 18020 +3. 启动 qiming-backend +``` + +## 5. qiming-file-server 安装、启动、验证 + +`qiming-file-server` 是本地文件服务和页面工程构建服务。当前开发环境固定端口为 `16000`。 + +`qiming-backend` 通过下面的地址调用它: + +```yaml +custom-page: + build-server-url: http://localhost:16000/api +``` + +因此建议在启动 `qiming-backend` 前先启动 `qiming-file-server`。 + +### 5.1 前置要求 + +确认 Node.js 和 npm 可用: + +```powershell +node -v +npm -v +``` + +`qiming-file-server` 的 `package.json` 要求 Node.js `>=22.0.0`。如果当前是 Node 20,可能可以启动,但建议切换到 Node 22,避免依赖或运行时兼容问题。 + +### 5.2 安装依赖 + +首次启动前执行: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qiming-file-server +npm install +``` + +如果已经安装过依赖,可以跳过这一步。 + +### 5.3 确认开发端口 + +开发环境配置文件: + +```text +D:\work\workspace\feitian-base\nvw\qiming-file-server\src\env.development +``` + +关键配置: + +```env +NODE_ENV=development +PORT=16000 +``` + +不要改成 `60000`。`60000` 是生产环境默认端口,当前本地开发统一使用 `16000`。 + +### 5.4 启动 + +打开一个新的 PowerShell 窗口,执行: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qiming-file-server +npm run dev +``` + +看到类似以下日志表示启动成功: + +```text +Server is running on port 16000 (development mode) +pnpm prune scheduler is started +``` + +不要关闭这个 PowerShell 窗口;关闭后文件服务也会停止。 + +### 5.5 验证 + +另开一个 PowerShell 窗口执行: + +```powershell +Test-NetConnection localhost -Port 16000 +Invoke-WebRequest http://localhost:16000/health +``` + +也可以用 curl: + +```powershell +curl.exe -f http://localhost:16000/health +``` + +期望返回 JSON,核心字段如下: + +```json +{ + "status": "ok", + "env": "development" +} +``` + +### 5.6 后端联通检查 + +确认 `qiming-backend` 的开发配置指向: + +```yaml +custom-page: + build-server-url: ${BUILD_SERVER_URL:http://localhost:16000/api} +``` + +如果页面工程上传、构建、读取文件相关接口失败,优先检查: + +```powershell +Test-NetConnection localhost -Port 16000 +Invoke-WebRequest http://localhost:16000/health +``` + +### 5.7 常见问题 + +#### 5.7.1 端口被占用 + +```powershell +netstat -ano | findstr :16000 +``` + +如果已有旧进程占用,先停止旧的 `qiming-file-server`,再重新执行: + +```powershell +npm run dev +``` + +#### 5.7.2 VS Code 终端环境和系统 PowerShell 不一致 + +如果系统 PowerShell 能启动,但 VS Code 终端不行,通常是 VS Code 没加载最新 PATH 或 Node 版本不一致。处理方式: + +```powershell +node -v +npm -v +where.exe node +where.exe npm +``` + +确认后重启 VS Code,再打开新终端。 + +## 6. qiming-backend 启动、配置检查、验证 + +`qiming-backend` 是主后端服务,Spring Boot HTTP 端口固定为 `18081`。 + +注意:启动 `qiming-backend` 后,进程内还会额外启动两个 Netty 代理端口: + +| 端口 | 服务 | 来源配置 | 说明 | +|---:|---|---|---| +| `18081` | Spring Boot 主服务 | `server.port` | 前端 `/api` 代理目标 | +| `18082` | custom-page HTTP 反向代理 | `custom-page.http-proxy.port` | 页面开发/生产预览代理入口 | +| `18086` | model-api-proxy | `model-api-proxy.port` | 后端内置模型 API 代理入口 | + +因此启动前要确认这三个端口都没有被占用。 + +### 6.1 启动前依赖检查 + +本地基础服务: + +```powershell +Test-NetConnection localhost -Port 3308 +Test-NetConnection localhost -Port 16379 +Test-NetConnection localhost -Port 16000 +Test-NetConnection localhost -Port 18020 +``` + +服务器基础服务: + +```powershell +Test-NetConnection 43.153.147.203 -Port 19530 +Test-NetConnection 43.153.147.203 -Port 19200 +Test-NetConnection 43.153.147.203 -Port 18087 +Test-NetConnection 43.153.147.203 -Port 18088 +``` + +本机待监听端口检查: + +```powershell +netstat -ano | findstr ":18081" +netstat -ano | findstr ":18082" +netstat -ano | findstr ":18086" +``` + +没有输出表示端口未被占用。 + +### 6.2 关键配置核对 + +配置文件: + +```text +D:\work\workspace\feitian-base\nvw\qiming-backend\app-platform-bootstrap\app-platform-web-bootstrap\src\main\resources\application-dev.yml +``` + +当前开发环境建议值: + +```yaml +server: + port: 18081 + +spring: + datasource: + dynamic: + datasource: + master: + url: jdbc:mysql://${DB_HOST:localhost}:3308/${DB_NAME:agent_platform} + data: + redis: + host: ${REDIS_HOST:localhost} + port: ${REDIS_PORT:16379} + +code: + execute: + url: ${CODE_EXECUTE_URL:http://localhost:18020/api/run_code_with_log} + +mcp: + proxy-base-url: ${MCP_PROXY_URL:http://localhost:18020} + +custom-page: + http-proxy: + host: ${CUSTOM_PAGE_PROXY_HOST:0.0.0.0} + port: ${CUSTOM_PAGE_PROXY_PORT:18082} + dev-server-host: ${DEV_SERVER_HOST:http://localhost} + prod-server-host: ${PROD_SERVER_HOST:http://localhost:18099} + build-server: + base-url: ${BUILD_SERVER_URL:http://localhost:16000/api} + ai-agent: + base-url: ${AI_AGENT_URL:http://43.153.147.203:18087} + docker-proxy: + enable: ${DOCKER_PROXY_ENABLE:true} + base-url: ${DOCKER_PROXY_URL:http://43.153.147.203:18088} + +model-api-proxy: + base-api-url: ${MODEL_API_BASE_URL:http://localhost:18086} + enable-model-proxy: ${MODEL_PROXY_ENABLE:true} + port: ${MODEL_PROXY_PORT:18086} +``` + +说明: + +- `custom-page.build-server.base-url` 指向本机 `qiming-file-server`,端口必须是 `16000`。 +- `custom-page.ai-agent.base-url` 指向服务器 `rcoder` 主服务,端口是 `18087`。 +- `custom-page.docker-proxy.base-url` 指向服务器 `rcoder` Pingora 代理,端口是 `18088`。 +- `custom-page.http-proxy.port=18082` 是后端自己启动的页面代理端口,不需要单独启动服务。 +- `model-api-proxy.port=18086` 是后端自己启动的模型代理端口。 +- `model-api-proxy.base-api-url` 必须和 `model-api-proxy.port` 对齐,本地开发使用 `http://localhost:18086`。 +- `custom-page.prod-server-host=18099` 需要另有静态服务/Nginx 提供构建后的 `DIST_TARGET_DIR` 内容;如果没有启动该静态服务,生产预览不可用,但不影响后端主服务启动。 +- `log-module.log.rust-service.base-url=8097` 是旧 Rust 日志服务,已废弃/可选,不纳入必启动项。 + +### 6.3 启动 + +打开新的 PowerShell 窗口: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qiming-backend +mvn spring-boot:run -pl app-platform-bootstrap/app-platform-web-bootstrap -Pdev +``` + +启动成功时应看到: + +```text +Tomcat started on port 18081 +http proxy server started at 0.0.0.0:18082 +Model proxy server started on port 18086 +Started PlatformApiApplication +``` + +不要关闭这个 PowerShell 窗口;关闭后后端服务会停止。 + +### 6.4 验证 + +另开 PowerShell 执行: + +```powershell +Test-NetConnection localhost -Port 18081 +Test-NetConnection localhost -Port 18082 +Test-NetConnection localhost -Port 18086 +Invoke-WebRequest http://localhost:18081/health +``` + +期望: + +```text +18081: TcpTestSucceeded True +18082: TcpTestSucceeded True +18086: TcpTestSucceeded True +/health: 返回成功 JSON +``` + +也可以用 curl: + +```powershell +curl.exe -f http://localhost:18081/health +``` + +### 6.5 常见问题 + +#### 6.5.1 Address already in use + +如果启动时报端口占用,分别检查: + +```powershell +netstat -ano | findstr ":18081" +netstat -ano | findstr ":18082" +netstat -ano | findstr ":18086" +``` + +`18081`、`18082`、`18086` 任意一个被占用,都会导致后端启动失败或能力不完整。 + +#### 6.5.2 MySQL 或 Redis 连接失败 + +先验证: + +```powershell +Test-NetConnection localhost -Port 3308 +Test-NetConnection localhost -Port 16379 +``` + +并确认配置: + +```yaml +DB_HOST=localhost +DB_NAME=agent_platform +DB_USERNAME=root +DB_PASSWORD=root +REDIS_HOST=localhost +REDIS_PORT=16379 +REDIS_PASSWORD=Byyagz@121 +``` + +#### 6.5.3 页面构建相关接口失败 + +先确认 `qiming-file-server`: + +```powershell +Invoke-WebRequest http://localhost:16000/health +``` + +后端配置应为: + +```yaml +custom-page: + build-server: + base-url: http://localhost:16000/api +``` + +#### 6.5.4 AI 页面开发调用失败 + +先确认服务器 rcoder: + +```powershell +curl.exe -f http://43.153.147.203:18087/health +curl.exe -f http://43.153.147.203:18088/health +``` + +后端配置应为: + +```yaml +custom-page: + ai-agent: + base-url: http://43.153.147.203:18087 + docker-proxy: + base-url: http://43.153.147.203:18088 +``` + +## 7. qiming 前端启动、配置检查、验证 + +`qiming` 是 PC 前端项目,本地开发端口固定为 `18000`。 + +前端开发代理: + +```text +qiming:18000 -> /api/ -> qiming-backend:18081 +``` + +因此启动前端前,建议先确认 `qiming-backend` 已经启动并通过 `/health` 验证。 + +### 7.1 前置要求 + +确认 Node.js、pnpm 可用: + +```powershell +node -v +pnpm -v +``` + +`qiming/package.json` 使用: + +```json +"packageManager": "pnpm@10.27.0" +``` + +如果 pnpm 不可用,先启用 Corepack: + +```powershell +corepack enable +corepack prepare pnpm@10.27.0 --activate +pnpm -v +``` + +### 7.2 安装依赖 + +首次启动前执行: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qiming +pnpm install +``` + +如果 `node_modules` 已存在且依赖没有变化,可以跳过。 + +### 7.3 确认前端端口 + +端口配置文件: + +```text +D:\work\workspace\feitian-base\nvw\qiming\.env +``` + +关键配置: + +```env +PORT=18000 +BABEL_CACHE=none +``` + +不要用下面方式改端口: + +```powershell +pnpm dev -- --port 18000 +``` + +也不要在 Umi 配置里加 `devServer`。当前项目的端口以 `.env` 文件为准。 + +### 7.4 确认后端代理 + +配置文件: + +```text +D:\work\workspace\feitian-base\nvw\qiming\config\config.development.ts +``` + +关键配置: + +```ts +proxy: { + '/api/': { + target: 'http://localhost:18081', + changeOrigin: true, + }, +} +``` + +启动前先确认后端可用: + +```powershell +Invoke-WebRequest http://localhost:18081/health +``` + +### 7.5 启动 + +打开新的 PowerShell 窗口: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qiming +pnpm dev +``` + +启动成功后应看到: + +```text +App listening at: + Local: http://localhost:18000 +``` + +如果日志里仍显示 `http://localhost:3000`,说明 `.env` 没有被当前启动进程正确读取,先停止前端,确认 `.env` 中 `PORT=18000` 后重新执行 `pnpm dev`。 + +### 7.6 验证 + +浏览器打开: + +```text +http://localhost:18000 +``` + +PowerShell 验证端口: + +```powershell +Test-NetConnection localhost -Port 18000 +``` + +验证前端代理到后端: + +```powershell +Invoke-WebRequest http://localhost:18000/api/health +``` + +如果 `http://localhost:18081/health` 正常,但 `http://localhost:18000/api/health` 不正常,优先检查 `config.development.ts` 的 proxy 配置。 + +### 7.7 常见问题 + +#### 7.7.1 Invalid config keys: devServer + +不要在 Umi 配置里添加: + +```ts +devServer: {} +``` + +这个项目使用 `@umijs/max`,该配置会触发: + +```text +Invalid config keys: devServer +``` + +端口请固定写在 `.env`: + +```env +PORT=18000 +``` + +#### 7.7.2 `PORT=18000 max dev` 或 `max dev --port 18000` 不生效 + +本项目已验证这两种方式可能仍然显示 `3000`。使用 `.env` 是当前确定可行方式。 + +#### 7.7.3 前端页面打开但接口失败 + +按顺序检查: + +```powershell +Invoke-WebRequest http://localhost:18081/health +Invoke-WebRequest http://localhost:18000/api/health +``` + +如果后端未启动,先回到第 6 节启动 `qiming-backend`。 + +## 8. qimingcode 启动、端口配置检查、验证 + +### 8.1 服务说明 + +`qimingcode` 是基于 OpenCode 的页面开发工具,开发模式下至少包含两个进程: + +| 端口 | 进程 | 说明 | +| --- | --- | --- | +| `18030` | OpenCode API Server | `packages/opencode`,源码默认端口是 `4096` | +| `18031` | Web UI / Vite | `packages/app`,源码默认端口是 `3000` | + +注意:`18030` 是 API 服务端口,`18031` 是浏览器访问端口。不要只启动 Web UI,否则页面能打开但无法连接 OpenCode API。 + +### 8.2 已检查到的默认端口 + +| 文件 | 默认值 | 本环境处理 | +| --- | --- | --- | +| `qimingcode/packages/opencode/src/server/adapter.bun.ts` | `4096` | 启动 API 时显式传 `--port 18030` | +| `qimingcode/packages/opencode/src/server/adapter.node.ts` | `4096` | 同上 | +| `qimingcode/packages/app/vite.config.ts` | `3000` | 启动 Web 时显式传 `--port 18031` | +| `qimingcode/packages/app/src/entry.tsx` | `VITE_OPENCODE_SERVER_PORT` 未设置时回退 `4096` | 启动 Web 前设置 `VITE_OPENCODE_SERVER_PORT=18030` | +| `qimingcode/packages/app/playwright.config.ts` | Web `3000`、API `4096` | 仅影响 Playwright 测试;运行测试时也要显式覆盖 | +| `qimingcode/packages/opencode/src/plugin/codex.ts` | `1455` | Codex OAuth 回调端口,不是 qimingcode 主服务端口 | +| `qimingcode/packages/opencode/src/mcp/oauth-provider.ts` | `19876` | MCP OAuth 回调端口,不是 qimingcode 主服务端口 | + +结论:源码默认端口不是错误,但不符合当前开发环境端口规划。启动时必须覆盖默认值。 + +### 8.3 基础环境检查 + +`qimingcode` 的 `packageManager` 是 `bun@1.3.13`,不要用 `pnpm install` 或 `npm install`。 + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingcode +bun --version +``` + +如果 `bun` 命令不存在,先安装 Bun,并重新打开 PowerShell 后再验证。 + +安装依赖: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingcode +bun install +``` + +### 8.4 启动 OpenCode API Server + +打开第一个 PowerShell 窗口: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingcode +bun run --cwd packages/opencode --conditions=browser ./src/index.ts serve --hostname 127.0.0.1 --port 18030 +``` + +启动成功后应看到类似输出: + +```text +opencode server listening on http://127.0.0.1:18030 +``` + +验证: + +```powershell +Test-NetConnection localhost -Port 18030 +Invoke-WebRequest http://localhost:18030/health +``` + +正常返回应包含: + +```json +{"healthy":true} +``` + +如果提示 `OPENCODE_SERVER_PASSWORD is not set; server is unsecured`,开发环境可以先忽略;对外暴露时必须配置访问控制。 + +### 8.5 启动 Web UI + +打开第二个 PowerShell 窗口: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingcode +$env:VITE_OPENCODE_SERVER_HOST = "localhost" +$env:VITE_OPENCODE_SERVER_PORT = "18030" +bun run --cwd packages/app dev -- --host 0.0.0.0 --port 18031 +``` + +浏览器打开: + +```text +http://localhost:18031 +``` + +验证端口: + +```powershell +Test-NetConnection localhost -Port 18031 +``` + +### 8.6 启动顺序 + +推荐顺序: + +1. 启动 `qimingcode` OpenCode API Server:`18030` +2. 启动 `qimingcode` Web UI:`18031` +3. 浏览器访问 `http://localhost:18031` + +如果先启动 Web UI,页面会按当前环境变量或默认值尝试连接 API;没有设置环境变量时会回退到 `http://localhost:4096`,这不符合当前端口规划。 + +### 8.7 Playwright 测试端口覆盖 + +如果后续要跑 `packages/app` 的 Playwright 测试,使用下面环境变量覆盖默认端口: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingcode\packages\app +$env:PLAYWRIGHT_PORT = "18031" +$env:PLAYWRIGHT_SERVER_HOST = "127.0.0.1" +$env:PLAYWRIGHT_SERVER_PORT = "18030" +bun run test:e2e +``` + +如果 `package.json` 中没有对应测试脚本,先执行: + +```powershell +bun run +``` + +查看当前可用脚本。 + +### 8.8 常见问题 + +#### 8.8.1 `Unsupported package manager specification (bun@1.3.13)` + +这是用 `pnpm install` 启动了 Bun 项目导致的。回到 `qimingcode` 根目录执行: + +```powershell +bun install +``` + +#### 8.8.2 Web UI 打开后连不上服务 + +先确认 API 服务: + +```powershell +Invoke-WebRequest http://localhost:18030/health +``` + +再确认启动 Web UI 的 PowerShell 中设置了: + +```powershell +$env:VITE_OPENCODE_SERVER_HOST = "localhost" +$env:VITE_OPENCODE_SERVER_PORT = "18030" +``` + +如果没有设置,Web UI 会默认连接 `http://localhost:4096`。 + +#### 8.8.3 端口被占用 + +检查端口: + +```powershell +Get-NetTCPConnection -LocalPort 18030,18031 -ErrorAction SilentlyContinue | + Select-Object LocalAddress,LocalPort,State,OwningProcess +``` + +如果 `18030` 被占用,优先停止旧的 OpenCode API 进程;如果 `18031` 被占用,优先停止旧的 Vite 进程。 + +## 9. qimingclaw 启动、端口检查、验证 + +### 9.1 服务说明 + +`qimingclaw` 是 Electron 桌面端开发工具。根目录没有 `dev` 脚本,必须启动 workspace 中的 `agent-electron-client` 包。 + +开发模式下主要涉及以下端口: + +| 端口 | 服务 | 说明 | +| --- | --- | --- | +| `60173` | qimingclaw Vite | Electron 渲染进程开发服务器,`dev:electron` 会等待此端口 | +| `60001` | Agent / ComputerServer | qimingclaw 内部 Agent 服务默认端口 | +| `60000` | FileServer | qimingclaw 内置文件服务默认端口,不等同于独立 `qiming-file-server` 的 `16000` | +| `18099` | MCP Proxy | qimingclaw 内置 MCP Proxy 默认端口 | +| `60002` | Lanproxy Local | qimingclaw 内置 lanproxy 本地端口 | +| `60008` | agent-gui-server | GUI Agent HTTP MCP 默认端口,开启 GUI MCP 时使用 | + +注意:这里的 `60000`、`18099` 是 qimingclaw 自己管理的默认端口,不要和主开发环境的 `qiming-file-server:16000`、`mcp-proxy:18020` 混淆。 + +### 9.2 基础环境检查 + +`qimingclaw` 使用 `pnpm@9.15.5`。 + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingclaw +node -v +pnpm -v +``` + +当前项目依赖里部分包要求 Node `>=22.0.0`。如果使用 Node `20.x`,`pnpm install` 可能只给出 `Unsupported engine` 警告,开发模式通常仍可继续;如果后续 Electron 或构建脚本异常,优先切换到 Node 22。 + +安装依赖: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingclaw +pnpm install +``` + +如果 Electron 下载超时,先配置 Electron 镜像后重新安装: + +```powershell +$env:ELECTRON_MIRROR = "https://npmmirror.com/mirrors/electron/" +pnpm install +``` + +### 9.3 开发环境配置 + +配置文件: + +```text +D:\work\workspace\feitian-base\nvw\qimingclaw\crates\agent-electron-client\.env.development +``` + +当前关键配置: + +```env +INJECT_GUI_MCP=true +QIMING_AGENT_LOG_FULL_SECRETS=true +ENABLE_GUI_AGENT_SERVER=true +``` + +说明: + +- `INJECT_GUI_MCP=true`:开发时注入 GUI MCP。 +- `ENABLE_GUI_AGENT_SERVER=true`:启用 `agent-gui-server` 模块。 +- `QIMING_AGENT_LOG_FULL_SECRETS=true`:开发调试时日志不脱敏,注意不要外发日志。 + +### 9.4 启动前端口检查 + +执行项目自带检查: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingclaw +pnpm --filter ./crates/agent-electron-client run check-ports:dev +``` + +正常情况下应看到以下端口均为空闲: + +```text +Agent(ComputerServer)=60001 +FileServer=60000 +MCP Proxy=18099 +Lanproxy=60002 +Vite=60173 +``` + +如果 `Vite (60173)` 被占用,先确认占用进程: + +```powershell +Get-NetTCPConnection -LocalPort 60173 -ErrorAction SilentlyContinue | + Select-Object LocalAddress,LocalPort,State,OwningProcess + +Get-Process -Id | Select-Object Id,ProcessName,Path +``` + +如果占用者是旧的 `electron` 或旧的 `vite` 进程,先关闭旧窗口或手动停止对应进程后再启动。 + +### 9.5 启动 + +打开新的 PowerShell 窗口: + +```powershell +cd D:\work\workspace\feitian-base\nvw\qimingclaw +pnpm --filter ./crates/agent-electron-client run dev +``` + +该命令会同时启动: + +- `dev:vite`:Vite 渲染进程,监听 `60173` +- `dev:electron`:等待 `http://localhost:60173` 后编译主进程并启动 Electron + +启动成功后会弹出 QimingClaw 桌面窗口。 + +### 9.6 验证 + +检查 Vite 端口: + +```powershell +Test-NetConnection localhost -Port 60173 +``` + +检查 Electron 进程: + +```powershell +Get-Process electron -ErrorAction SilentlyContinue | + Select-Object Id,ProcessName,Path +``` + +如果需要确认 qimingclaw 内部端口占用情况: + +```powershell +Get-NetTCPConnection -LocalPort 60000,60001,60002,60008,18099,60173 -ErrorAction SilentlyContinue | + Select-Object LocalAddress,LocalPort,State,OwningProcess | + Sort-Object LocalPort +``` + +### 9.7 当前已验证现象 + +如果执行端口检查时看到: + +```text +[占用] Vite (60173) PID=... +``` + +并且: + +```powershell +Get-Process -Id +``` + +显示为: + +```text +ProcessName = electron +Path = ...\qimingclaw\node_modules\.pnpm\electron@...\electron... +``` + +说明已有一份 qimingclaw 开发进程在运行,不要重复启动。需要重启时,先关闭当前 Electron 窗口,再重新执行第 9.5 节启动命令。