# codex_web02 **Repository Path**: gaoziteng/codex_web02 ## Basic Information - **Project Name**: codex_web02 - **Description**: Demo project for Spring Boot - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-07 - **Last Updated**: 2026-05-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # codex_web `codex_web` 是一个用于在手机浏览器里远程控制本机 Codex 会话的轻量 Web 控制台。 它运行在 macOS 或 Linux 上,后端会启动一个长期存活的 `codex app-server` 进程,通过 app-server 协议打开 Codex thread,并把后续消息继续发送到已经打开的 thread,而不是每条消息都重新启动 Codex。会话、消息、运行状态、Codex thread 状态和事件流都会写入 SQLite,所以手机网络断开后,Codex 仍会在后端继续处理;浏览器恢复连接后,会按事件 ID 继续拉取漏掉的消息。 ## 功能 - 适合手机使用的 Codex 聊天界面。 - 后端复用一个长期运行的 Codex app-server。 - 支持弱网断线后继续接收历史事件。 - UI 创建的会话和本机导入的 Codex 会话分 Tab 展示。 - 支持按会话标题和工作目录搜索。 - 支持按工作目录分组。 - 支持收藏会话。 - 支持打开和关闭 Codex 会话,减少本机进程占用。 - 支持同工作目录 Fork 会话。 - 支持调整模型、推理强度和执行模式。 - 支持 Markdown 渲染和代码高亮。 - 支持选择或粘贴多张图片发送给 Codex。 - 支持查看当前会话工作目录的 `git status` 和 `git diff`。 - 支持公网网关,用于电脑在内网时从手机访问。 ## 安全说明 `codex_web` 当前没有内置登录认证。 建议只在可信局域网、VPN、SSH 隧道或带认证的反向代理后使用。不要在没有任何认证和访问控制的情况下直接暴露到公网。 默认执行模式是 `yolo`,对应 Codex 的 `danger-full-access`。这意味着 Codex 可能在本机执行命令、修改文件。只在你信任的机器和项目目录中使用。 如果需要公网访问,建议至少使用下面任意一种保护方式: - VPN - Tailscale - WireGuard - Nginx Basic Auth - 防火墙白名单 - SSH 隧道 ## 环境要求 必需: - macOS 或 Linux。 - Python 3.6 或更新版本。 - 已安装 Codex CLI。 - 运行 `codex_web` 的机器上已经完成 Codex 登录或认证。 - `codex app-server --listen stdio://` 可以正常启动。 不支持 Python 2。 可选: - Node.js:只在运行 `node --check` 或部分部署脚本时需要。 - `ssh`、`rsync`:只在公网网关或远程部署场景需要。 检查命令: ```bash python3 --version codex --version codex app-server --listen stdio:// ``` 最后一条命令如果没有立刻报错,说明 app-server 基本可用。确认后可以按 `Ctrl+C` 停止。 ## 安装 从仓库拉代码: ```bash git clone <你的仓库地址> codex_web cd codex_web ``` 核心服务不需要额外安装 Python 依赖,使用 Python 标准库和本机已安装的 Codex CLI。 ## 本地启动 在仓库目录中启动: ```bash python3 -m codex_web.server \ --host 0.0.0.0 \ --port 8765 \ --cwd /data/idea ``` 参数说明: - `--host 0.0.0.0`:允许手机通过局域网访问。 - `--port 8765`:Web 服务端口。 - `--cwd /data/idea`:默认工作目录。 启动成功后会打印类似: ```text codex_web is running Local: http://127.0.0.1:8765/ Phone: http://192.168.x.x:8765/ ``` 手机和电脑在同一个可互通网络时,手机打开 `Phone:` 后面的地址即可。 如果你不在仓库目录里启动,可以设置 `PYTHONPATH`: ```bash PYTHONPATH=/path/to/codex_web python3 -m codex_web.server \ --host 0.0.0.0 \ --port 8765 \ --cwd /data/idea ``` 也可以使用仓库里的启动入口: ```bash python3 /path/to/codex_web/run_codex_web.py \ --host 0.0.0.0 \ --port 8765 \ --cwd /data/idea ``` 启动时程序默认会尝试杀掉已经占用目标端口的旧进程。如果不想自动处理旧进程,可以加: ```bash python3 -m codex_web.server --host 0.0.0.0 --port 8765 --no-kill-existing ``` ## 基本使用 1. 用手机浏览器打开 `Phone:` 地址。 2. 点击新建会话按钮。 3. 填写会话标题。 4. 填写工作目录。`/data/idea/` 只是默认推荐路径,不是强制限制。 5. 如果工作目录不存在,后端会自动创建。 6. 进入会话后直接发送消息。 7. 后续消息会继续发送给当前已打开的 Codex thread。 8. 在会话菜单里可以打开、关闭、Fork、删除、查看变更、修改模型设置。 说明: - 关闭会话:关闭当前 Codex thread 订阅,减少本机进程或会话占用,不等于删除历史。 - 删除会话:删除 UI 会话,并尝试删除经过校验的 Codex rollout 文件。 - Fork 会话:只支持同工作目录 Fork。 - 收藏会话:收藏后会出现在收藏 Tab。 ## 图片发送 聊天输入框支持: - 一次选择多张图片。 - 在输入框里粘贴图片。 - 发送前预览图片。 - 发送前删除某张图片。 - 文字加图片一起发送。 - 纯图片消息。 - 历史消息中展示已发送图片。 限制: - 每条消息最多 8 张图片。 - 单张图片最大 6 MB。 - 每条消息图片总量最大 12 MB。 - 支持 PNG、JPEG、WEBP、GIF。 ## 配置项 可以通过环境变量配置: - `CODEX_WEB_HOST`:默认监听地址,默认 `127.0.0.1`。 - `CODEX_WEB_PORT`:默认端口,默认 `8765`。 - `CODEX_WEB_CWD`:默认工作目录。 - `CODEX_WEB_STATE_DIR`:状态目录,默认 `.codex_web`。 - `CODEX_WEB_WORKSPACE_BASE`:UI 新建会话时推荐的默认工作目录前缀,默认 `/data/idea`。 - `CODEX_WEB_DEFAULT_MODEL`:默认模型,默认 `gpt-5.5`。 - `CODEX_WEB_DEFAULT_REASONING_EFFORT`:默认推理强度,默认 `xhigh`。 - `CODEX_WEB_DEFAULT_EXECUTION_MODE`:默认执行模式,默认 `yolo`。 - `CODEX_WEB_APP_SERVER_CMD`:启动 Codex app-server 的命令,默认 `codex app-server --listen stdio://`。 - `CODEX_WEB_GATEWAY_ENABLED`:在 `scripts/start_launch_agent.sh` 中设置为 `0` 可禁用公网网关隧道。 - `CODEX_WEB_GATEWAY_SSH_HOST`:公网网关 SSH 目标。 - `CODEX_WEB_GATEWAY_REMOTE_HOST`:反向隧道远端绑定地址,默认 `127.0.0.1`。 - `CODEX_WEB_GATEWAY_REMOTE_PORT`:反向隧道远端端口,默认 `18765`。 - `CODEX_WEB_GATEWAY_LOCAL_HOST`:本机服务地址,默认 `127.0.0.1`。 示例: ```bash export CODEX_WEB_STATE_DIR=/opt/codex_web/.codex_web export CODEX_WEB_WORKSPACE_BASE=/data/idea export CODEX_WEB_DEFAULT_MODEL=gpt-5.5 export CODEX_WEB_DEFAULT_REASONING_EFFORT=xhigh export CODEX_WEB_DEFAULT_EXECUTION_MODE=yolo python3 -m codex_web.server --host 0.0.0.0 --port 8765 --cwd /data/idea ``` ## 公网网关 如果运行 Codex 的电脑在内网,手机无法直接访问,可以在公网服务器上运行 `codex_web.gateway`,再由内网电脑建立 SSH 反向隧道。 访问链路: ```text 手机浏览器 -> 公网服务器: -> SSH 反向隧道 -> 本机 codex_web:8765 ``` 公网服务器上运行: ```bash cd /opt/codex_web export CODEX_WEB_PUBLIC_PORT= export CODEX_WEB_TUNNEL_PORT= python3 -m codex_web.gateway \ --host 0.0.0.0 \ --port "$CODEX_WEB_PUBLIC_PORT" \ --target-host 127.0.0.1 \ --target-port "$CODEX_WEB_TUNNEL_PORT" ``` 如有防火墙,需要放行 `/tcp`。 内网 Codex 机器上运行: ```bash cd /path/to/codex_web export CODEX_WEB_GATEWAY_SSH_HOST=user@public-server export CODEX_WEB_GATEWAY_REMOTE_HOST=127.0.0.1 export CODEX_WEB_GATEWAY_REMOTE_PORT= export CODEX_WEB_GATEWAY_LOCAL_HOST=127.0.0.1 export CODEX_WEB_PORT=8765 ./scripts/start_gateway_tunnel.sh ``` 然后手机访问: ```text http://public-server:/ ``` 如果公网网关返回 `503`,说明公网服务器可以访问,但 SSH 反向隧道没有连上。 ## systemd 运行 本机 `codex_web` 服务示例: ```ini [Unit] Description=codex_web After=network.target [Service] Type=simple WorkingDirectory=/opt/codex_web Environment=CODEX_WEB_STATE_DIR=/opt/codex_web/.codex_web Environment=CODEX_WEB_WORKSPACE_BASE=/data/idea ExecStart=/usr/bin/python3 -m codex_web.server --host 0.0.0.0 --port 8765 --cwd /data/idea Restart=always RestartSec=3 [Install] WantedBy=multi-user.target ``` 保存为 `/etc/systemd/system/codex-web.service` 后启用: ```bash systemctl daemon-reload systemctl enable --now codex-web.service systemctl status codex-web.service ``` 公网网关服务示例: ```ini [Unit] Description=codex_web public gateway After=network.target [Service] Type=simple WorkingDirectory=/opt/codex_web ExecStart=/usr/bin/python3 -m codex_web.gateway --host 0.0.0.0 --port --target-host 127.0.0.1 --target-port Restart=always RestartSec=3 [Install] WantedBy=multi-user.target ``` ## 制作干净源码包 如果不想直接发 Git 仓库,也可以制作干净源码包: ```bash ./scripts/package_clean_source.sh ``` 脚本会把压缩包写入 `dist/`,排除本机运行状态和生成文件,并生成 `.sha256` 校验文件。它会先在系统临时目录中打包,再移动到 `dist/`,所以不会出现 `tar: Can't add archive to itself`。 也可以指定输出路径: ```bash ./scripts/package_clean_source.sh /tmp/codex_web.tar.gz ``` 源码包会排除: - `.git/` - `.codex_web/` - `.idea/`、`.vscode/` - `dist/`、`target/`、`build/` - Python 字节码和 `__pycache__/` - 日志文件和已有的 `codex_web*.tar.gz` ## 验证 语法检查: ```bash python3 -m py_compile run_codex_web.py codex_web/*.py tests/*.py node --check codex_web/static/app.js ``` 测试: ```bash python3 -m unittest discover -s tests ``` 运行检查: ```bash curl -sS http://127.0.0.1:8765/api/bootstrap curl -sS http://127.0.0.1:8765/app.js | grep pendingImages ``` ## 常见问题 ### `No module named codex_web` 通常是没有在仓库根目录运行。 解决: ```bash cd /path/to/codex_web python3 -m codex_web.server --host 0.0.0.0 --port 8765 ``` 或者设置 `PYTHONPATH`: ```bash PYTHONPATH=/path/to/codex_web python3 -m codex_web.server --host 0.0.0.0 --port 8765 ``` ### `Address already in use` 检查占用端口的进程: ```bash lsof -nP -iTCP:8765 -sTCP:LISTEN ss -ltnp | grep 8765 netstat -ltnp | grep 8765 ``` 默认情况下,`codex_web` 启动时会尝试杀掉旧监听进程;如果加了 `--no-kill-existing`,则不会自动处理。 ### 手机打不开页面 检查: - 服务是否用 `--host 0.0.0.0` 启动。 - 手机和电脑是否在同一个可互通网络。 - 手机访问的是电脑局域网 IP,不是 `127.0.0.1`。 - 电脑防火墙是否允许访问对应端口。 ### Codex 没有响应 检查: ```bash codex --version codex app-server --listen stdio:// ``` 如果 Codex 需要登录或认证,请先在运行 `codex_web` 的机器上完成。 ### 公网网关返回 503 说明公网网关进程在运行,但 SSH 反向隧道没有连上。检查: ```bash ps aux | grep start_gateway_tunnel ss -ltnp | grep -E '|' ``` ### 图片发送失败 检查: - 单张图片不能超过 6 MB。 - 每条消息图片总量不能超过 12 MB。 - 只支持 PNG、JPEG、WEBP、GIF。 ## API 概览 - `GET /api/bootstrap`:获取服务默认配置和 UI 配置。 - `GET /api/sessions?source=ui|imported|favorite`:获取会话列表。 - `POST /api/sessions`:创建会话。 - `GET /api/sessions/{id}`:获取会话详情和分页消息。 - `POST /api/sessions/{id}/messages`:向现有 Codex thread 发送文字或图片消息。 - `GET /api/sessions/{id}/events?after=N`:拉取漏掉的事件。 - `GET /api/sessions/{id}/events/stream?after=N`:通过 SSE 接收可恢复事件流。 - `POST /api/sessions/{id}/open`:打开或恢复 Codex thread。 - `POST /api/sessions/{id}/close`:关闭 Codex thread 订阅。 - `DELETE /api/sessions/{id}`:调用 Codex `thread/archive` 归档会话,并从列表移除;不会物理删除 rollout 文件。 - `POST /api/sessions/{id}/fork`:在相同工作目录 Fork 会话。 - `GET /api/sessions/{id}/fork-tree`:查看与当前会话关联的 Fork 分支树。 - `POST /api/sessions/{id}/settings`:更新模型、推理强度和执行模式。 - `GET /api/sessions/{id}/changes`:查看 `git status` 和 `git diff`。