Files
boss/README.md

300 lines
21 KiB
Markdown
Raw 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.

# Boss 控制台 MVP
这个仓库当前已经收口成“下一条 AI 线程不需要重新摸索结构和部署方式”的状态。真实实现是一套基于 `Next.js App Router` 的移动控制台,加一个本地 `device-agent`,持久化仍然是 `data/boss-state.json`,部署链路是 `systemd + Caddy + launchd`
## 先读哪里
按这个顺序看,交接成本最低:
1. `docs/architecture/ai_handoff_index_cn.md`
2. `docs/architecture/repo_map_cn.md`
3. `docs/architecture/current_runtime_and_deploy_status_cn.md`
4. `docs/architecture/api_and_service_inventory_cn.md`
5. `docs/architecture/boss_server_connection_and_deploy_cn.md`
6. `prompts/codex_fullstack_build_and_deploy_prompt_cn.md`
## 当前有效目录
- `src/app`:当前 Web 页面和 API 路由
- `src/components`:共享 UI 和交互组件
- `src/lib`:文件型状态模型和聚合投影视图
- `local-agent`:本地设备端心跳 + thread-context 上报服务
- `deployment``Caddy``systemd``launchd` 配置
- `scripts`:本地启动、安装、远端部署脚本
- `design`Pencil 原稿和导出图
- `android`:原生 Android 客户端工程和 APK 构建目录
- `docs/architecture`:当前权威中文文档
- `prompts`:交给其他 Codex 线程的提示词
## 当前仅作参考或占位的目录
- `docs/source-material`:历史材料,不是运行时真相
- `deploy`:空占位目录,不参与当前部署
- `src/boss_control`:空占位目录,不参与当前运行
- `src/boss_device_agent`:空占位目录,不参与当前运行
## 当前运行状态2026-03-29
本地:
- `npm run lint` 已通过
- `npm run build` 已通过
- `GET http://127.0.0.1:3000/api/health` 正常
- `GET http://127.0.0.1:3000/api/v1/conversations` 正常
- `GET http://127.0.0.1:3000/api/v1/projects/master-agent` 正常,主 Agent 项目页已能显示最近 APP 日志
- `GET http://127.0.0.1:3000/api/v1/accounts` 正常,已返回主 GPT / 备用 GPT / API 容灾账号摘要
- `GET http://127.0.0.1:3000/api/v1/devices/mac-studio/skills` 正常,已返回本机同步 Skill 列表
- `POST http://127.0.0.1:3000/api/auth/login` 正常,会写入 `boss_session` Cookie
- `GET http://127.0.0.1:3000/api/auth/session` 正常
- `POST http://127.0.0.1:3000/api/auth/restore` 正常,已验证可用原生 restore token 恢复登录态
- `POST http://127.0.0.1:3000/api/v1/projects/master-agent/messages` 正常,已验证可通过 `Mac Studio local-agent -> 本机 Master Codex Node -> 回写项目账本` 返回真实主 Agent 回复
- `POST http://127.0.0.1:3000/api/auth/logout` 正常,退出后访问受保护 `/api/v1/*` 会返回 `401`
- `GET http://127.0.0.1:3000/api/v1/user/ota/package` 正常,当前会返回最新 APK 包
- `GET http://127.0.0.1:4317/health` 正常
- `GET http://127.0.0.1:4317/api/v1/skills` 正常,已返回本机扫描到的 Codex Skill
- `POST http://127.0.0.1:4317/api/v1/heartbeat` 正常,且会顺带触发 `thread-context` 上报
- `launchd` 已加载:`~/Library/LaunchAgents/com.hyzq.boss.local-agent.plist`
服务器:
- 服务器地址:`106.53.170.158`
- 代码路径:`/opt/boss`
- `boss-web.service` 正常
- `caddy.service` 正常
- `postfix.service` 正常
- `dovecot.service` 正常
- `GET http://127.0.0.1:3000/api/health` 正常
- `GET http://127.0.0.1:3000/api/v1/conversations` 正常
域名和 HTTPS
- 服务器本机 `dig +short boss.hyzq.net` 返回 `106.53.170.158`
- 服务器本机 `curl --resolve boss.hyzq.net:443:127.0.0.1 https://boss.hyzq.net -I` 返回 `307` 并跳转到 `/auth/login`
- 当前本机网络 `dig +short boss.hyzq.net` 仍返回 `198.18.1.188`
- 当前本机网络 `curl -I http://boss.hyzq.net` 返回 `308`
- 当前本机网络 `curl -I https://boss.hyzq.net` 返回 `HTTP/2 307` 并跳转到 `/auth/login`
- 当前本机网络 `curl https://boss.hyzq.net/api/health` 返回 `{"ok":true,...}`
- 当前本机网络 `curl https://boss.hyzq.net/api/v1/conversations` 已返回真实聚合数据
- 当前本机网络 `nc -vz boss.hyzq.net 25 587 993` 全部成功
当前结论更新为:
- 当前网络下 `boss.hyzq.net` 的 HTTP/HTTPS 已可达
- `Caddy/TLS` 和外部 `443` 路径都已经能实际返回页面跳转
- 公网域名下的 Web API 也已经能实际返回健康探针和业务数据
- 服务器上的 `Postfix + Dovecot` 已部署完成,公网 `25 / 587 / 993` 当前也已经可达
- 但当前网络下 `dig` 仍显示 `198.18.1.188`,说明这里可能存在代理层、分裂 DNS 或中间入口,不要再把这个解析值自动当成错误配置
Android APK
- 已生成 Android debug APK`android/app/build/outputs/apk/debug/app-debug.apk`
- 已生成 Android signed release APK`android/app/build/outputs/apk/release/app-release.apk`
- `npm run apk:release` 还会额外产出带版本号的文件:`android/app/build/outputs/apk/release/boss-android-v{versionName}-release.apk`
- 当前最新 release 构建版本:`2.5.2``versionCode=15`
- 当前 APK 已切到原生 Android 客户端:`MainActivity + BossApiClient + 原生 XML 布局`
- 当前原生活动页已经覆盖会话首页、项目详情、项目目标、版本记录、会话信息、群资料、发起群聊、消息转发、线程详情、设备详情、添加设备、账号与安全、设置、AI 账号、技能、运维中心、关于
- 当前原生一级体验已回退到微信式交互:`会话 / 设备 / 我的` 固定底部 tab会话首页是简单聊天列表`主 Agent / 审计对话` 以普通置顶会话样式排在最前;项目详情页是聊天优先,只保留 `项目目标 / 版本记录` 两个轻入口
- 当前会话首页右上角已切回 `+` 入口:直接从首页发起独立群聊;设备页右上角仍是 `+添加`
- 当前聊天列表已切到“线程 = 会话窗口”的结构:主标题显示线程名,副标题显示所属文件夹名,右下角显示后台活跃数量动态图标;同一文件夹下多个线程会显示成多个独立聊天窗口
- 当前会话信息页已经支持按微信最新逻辑改线程名;群聊会作为独立新会话创建,默认自动命名,创建后可在群资料页改名
- 原生顶部安全区当前已补齐状态栏 inset 处理,并把首页 / 会话信息 / 群资料 / 发起群聊 / 转发目标等页面的顶部操作区域收回到可点击安全区内
- 当前消息转发已经切到微信式链路:长按消息可直接 `转发 / 多选 / 复制 / 删除`,多选后底部只保留 `转发`,统一进入原生会话选择页
- 当前单条消息转发会在目标会话里显示为普通转发消息;多条消息会合并成一张“聊天记录”卡片,不再走旧的备注转发页
- 当前 `设备``我的` 根页已收口为简单列表;`运维与修复 / AI 账号 / 技能` 保留在一级 `我的``审计对话` 作为置顶会话保留在会话首页
- 原生客户端当前直接调用 `https://boss.hyzq.net` 的 Boss API不再打开 WebView
- `2.0.1` 已修复华为真机上因 `Theme.SplashScreen``AppCompatActivity` 不兼容导致的启动闪退
- `2.1.0` 已在本机连接的华为真机上完成签名包覆盖安装与启动复核,原生三栏入口和子活动页声明已全部接通
- `2.1.1` 已补上原生 OTA 下载链路:关于页会直接请求受保护的 `/api/v1/user/ota/package`,下载完成后可拉起系统安装器
- `2.2.0` 已把原生 UI 从控制台风格回退到微信式简单列表和聊天优先视图,并复核了设备页 / 我的页 / 深层高级入口
- `2.2.1` 已继续补齐原生交互细节:聊天页发送后会先出现本地“发送中”气泡,关于页会展示 OTA 下载进度 / 重试 / 安装授权提示,根 tab 会记住用户上次停留位置并改成“再按一次返回进入后台”
- `2.3.0` 已把会话模型切到“线程 = 聊天窗口”,补上文件夹名副信息、后台活跃数量动态图标、微信式会话信息页、线程改名、独立群聊创建、群资料页,以及 `主 Agent / 审计对话` 普通置顶会话化
- `2.4.0` 已把消息转发切到微信式原生链路:聊天页支持长按消息操作、多选合并转发、统一目标会话选择页;单条消息转发显示为普通转发消息,多条消息转发显示为“聊天记录”卡片
- `2.5.0` 已补齐聊天附件主链:原生聊天框左侧 `+` 会打开底部抽屉,支持图片 / 视频 / 文件发送;默认走服务器文件存储,`我的 > 附件与存储` 可切到阿里 OSS 私有桶;附件消息已支持下载 / 打开、手动分析、自动分析状态,以及带 task token 的主 Agent 附件分析链接
- `2.5.1` 继续收口微信式原生 UI聊天页普通态顶部已隐藏刷新按钮只保留右上角“信息”发起群聊页顶部说明和选择区已压成更轻的会话式密度候选线程继续复用微信式会话卡片
- `2.5.2` 继续补齐深层原生页:`项目目标 / 版本迭代记录 / 会话信息 / 群资料` 已进一步向设计图收口;附件消息卡片的分析状态和动作文案也压成了更轻的微信式层级
## 本地启动
开发态:
```bash
cd /Users/kris/code/boss
npm install
npm run dev
```
构建态:
```bash
cd /Users/kris/code/boss
npm run build
npm start
```
说明:
- `npm run build` 前会自动清理 `.next`,避免旧目录残留导致 `ENOTEMPTY`
默认入口:
- 登录页:[http://127.0.0.1:3000/auth/login](http://127.0.0.1:3000/auth/login)
- 会话页:[http://127.0.0.1:3000/conversations](http://127.0.0.1:3000/conversations)
- 设备页:[http://127.0.0.1:3000/devices](http://127.0.0.1:3000/devices)
## 设备端本地服务
手动启动:
```bash
cd /Users/kris/code/boss
./scripts/start-local-agent.sh ./local-agent/config.example.json
```
安装常驻 `launchd`
```bash
cd /Users/kris/code/boss
./scripts/install-local-launchagent.sh
```
如需把常驻 agent 指回本地开发控制面:
```bash
cd /Users/kris/code/boss
./scripts/install-local-launchagent.sh /Users/kris/code/boss/local-agent/config.example.json
```
device-agent 当前职责:
- 上报设备状态、账号、5h/7d 额度和项目列表
- 向云端 `/api/device-heartbeat` 发心跳
- 向云端 `/api/v1/workers/{workerId}/thread-context` 发线程预算更新
- 递归扫描本机 `~/.codex/skills`,并同步到云端 `/api/v1/devices/[deviceId]/skills`
- 轮询云端 `/api/v1/master-agent/tasks/claim`,并用当前电脑已登录的 `codex` 账号执行主 Agent 任务
- 将主 Agent 执行结果回写到云端 `/api/v1/master-agent/tasks/[taskId]/complete`
- 提供本地 `/health``/api/v1/device``/api/v1/skills``/api/v1/heartbeat`
当前常驻默认值:
- `launchd` 默认加载 `local-agent/config.cloud.json`,控制面指向 `https://boss.hyzq.net`
- `local-agent/config.example.json` 保留给本地 `127.0.0.1:3000` 回环开发
## 部署入口
- 服务器连接与部署:`docs/architecture/boss_server_connection_and_deploy_cn.md`
- 服务器调试 skill`$HOME/.codex/skills/boss-server-debug/SKILL.md`
- 远端部署脚本:`scripts/deploy-server.sh`
- 远端邮件部署脚本:`scripts/install-server-mail.sh`
- 远端初始化脚本:`scripts/bootstrap-server.sh`
- APK 发布脚本:`scripts/publish-apk-to-public.sh`
- `systemd` 配置:`deployment/systemd/boss-web.service`
- `Caddy` 配置:`deployment/Caddyfile`
- 邮件配置:`deployment/mail/`
- Android 原生入口:`android/app/src/main/java/com/hyzq/boss/MainActivity.java`
- Android API 客户端:`android/app/src/main/java/com/hyzq/boss/BossApiClient.java`
- Android 原生会话页:`android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java`
- Android 原生设备页:`android/app/src/main/java/com/hyzq/boss/DeviceDetailActivity.java`
- Android 原生我的页:`android/app/src/main/java/com/hyzq/boss/AiAccountsActivity.java``android/app/src/main/java/com/hyzq/boss/OpsCenterActivity.java``android/app/src/main/java/com/hyzq/boss/SettingsActivity.java`
- Android 微信式 surface contract`android/app/src/main/java/com/hyzq/boss/WechatSurfaceMapper.java`
- Android 聊天页布局:`android/app/src/main/res/layout/activity_project_chat.xml`
- 服务器环境示例:`.env.server.example`
当前 `scripts/deploy-server.sh`
- 优先从 macOS Keychain 读取 `ubuntu@106.53.170.158` 的密码
- 如果 Keychain 不可用,再回退读取 `BOSS_SERVER_PASS`
- 当前已明确排除 `data/` 目录,部署不会再覆盖服务器上的 `boss-state.json`
- 部署脚本当前会先在本机执行 `npm run build`,再把本机已经验证通过的 `.next` 构建产物同步到服务器
- 同步前会先在服务器上删除旧 `.next` 并修正 `/opt/boss` 所有权,避免 rsync 被历史 root 产物卡住
- 服务器当前不再现编 Next standalone而是直接重启使用本机同步过去的构建产物避免服务器端 tracing / 权限差异导致部署失败
- 远端重启服务后会自动执行一次 `curl -fsS http://127.0.0.1:3000/api/health`
APK 构建:
```bash
cd /Users/kris/code/boss
npm run apk:debug
```
```bash
cd /Users/kris/code/boss
npm run apk:release
```
```bash
cd /Users/kris/code/boss
npm run aab:release
```
说明:
- `npm run apk:debug` 现在会在 Gradle 构建完成后自动执行 `scripts/publish-apk-to-public.sh`
- `npm run apk:release` 会先准备本机 release keystore再构建 signed release APK并发布到 `public/downloads`
- 最新 APK 会同步到 `public/downloads/boss-android-latest.apk`
- 同时也会额外保留一份带版本号的 APK`public/downloads/boss-android-v{versionName}-{flavor}.apk`
- `npm run aab:release` 会先准备本机 release keystore再构建 signed release AAB并发布到 `public/downloads`
- 最新 AAB 会同步到 `public/downloads/boss-android-latest.aab`
- 同时也会额外保留一份带版本号的 AAB`public/downloads/boss-android-v{versionName}-{flavor}.aab`
- AAB 归档元数据会写入 `public/downloads/boss-android-latest-aab.json`
- OTA 下载入口固定走受保护的 `GET /api/v1/user/ota/package`
- release 签名文件当前放在本机:
- `android/keystores/boss-release.keystore`
- `android/signing/release-signing.properties`
- 以上文件已加入 `.gitignore`,不会进仓库
## 关键实现说明
- 当前持久化是真正生效的文件存储:`data/boss-state.json`
- Web 生产启动和服务器 `systemd` 都显式设置了 `BOSS_STATE_FILE`,避免 Next standalone 误把状态写进 `.next/standalone/data/`
- Web 生产启动、服务器 `systemd` 和部署构建当前都显式设置了 `BOSS_RUNTIME_ROOT`,避免 `process.cwd()` 在 standalone / 服务器构建阶段误把整个仓库根目录带进 tracing
- `next.config.ts` 已显式排除 `deployment / docs / design / local-agent / prompts / scripts / android` 等非运行时目录,避免服务器端 standalone tracing 卷入运维资产导致构建失败
- 文件写入已经改成串行事务队列 + 原子写入 + `data/boss-state.json.bak` 备份恢复,`heartbeat` 和 APP 日志并发写不会再互相覆盖
- 当前文件存储里已经包含:
- `projects / messages / goals / versions`
- `authAccounts / otaUpdates / otaUpdateLogs`
- `threadContextSnapshots / threadHandoffPackages / threadContextAlerts`
- `deviceEnrollments`
- `deviceSkills / appLogs`
- `opsFaults / opsRepairTickets / opsRepairVerifications`
- `auditRequests / auditResults / capabilities`
- 根布局会挂载 `AppLogBridge`前端路由切换、运行时异常、发送消息、OTA 操作都会通过 `/api/v1/app-logs` 实时同步到服务器
- Web 端根布局当前仍保留 `NativeAppBridge`,用于浏览器态与历史桥接兼容;当前正式 APK 已改为原生 Activity + 原生 API 客户端,不再依赖 WebView
- APP 日志桥已经改成会话感知:只会按当前登录账号解析绑定设备,不再在未登录页默认按全局管理员设备写日志
- APP 外壳已经从“桌面预览卡片”切回真机态:移动端不再渲染假的 `9:41 / 5G` 状态栏,底部 `会话 / 设备 / 我的` 导航固定在视口底部,背景改为全屏 cover不再出现圆角矩形外壳
- 原生 Android 当前也和这套产品口径对齐:根页采用微信式简单列表,项目聊天页改成消息流优先,`设备 / 我的` 页不再展示控制台式统计卡片
- 原生聊天页当前会即时渲染本地发送中消息,并且只有在用户接近底部或本次发送是主动触发时才自动滚到底
- 登录成功后的进入首页链路已做稳态处理:会先确认 `/api/auth/session` 可读,再执行 `replace(/conversations)`,并附带一次原生级兜底跳转,避免真机 WebView 偶发停留在“正在进入会话首页”
- `/api/v1/events` 已作为 SSE 出口使用,会话页、设备页、技能页和项目详情页会按事件自动刷新,不再只靠手动刷新
- 我的页新增 `技能` 入口,`/me/skills` 会按设备分组展示 Skill并支持一键复制调用语句
- 我的页新增 `AI 账号` 入口,`/me/ai-accounts` 会展示主 GPT / 备用 GPT / API 容灾,并明确主链路优先走已登录 `ChatGPT Plus / Codex``Master Codex Node`
- API 容灾当前不走服务器预置 Key而是由用户在 APP 的 `我的 > AI 账号` 中自行配置 `OpenAI API` 账号
- 设备页当前只展示已接入生产链路的设备,历史演示脏数据已经从正式设备视图、运维视图和审计视图中剔除
- 登录页当前已临时切到免验证模式,点击“登录”会直接进入会话首页
- 认证现在已经有最小会话链路:登录后会写入 `boss_session` Cookie默认保持 30 天,`会话 / 设备 / 我的 / 线程` 页面以及主要 `/api/v1/*` 接口都要求有效会话
- 新增 `GET /api/auth/session``POST /api/auth/logout``POST /api/auth/restore`
- 原生 Android 客户端当前会把 `boss_session / restore token / account` 存到 `SharedPreferences`,用于重启后恢复会话
- 验证码新增防刷与防重放60 秒冷却、15 分钟窗口限流,登录连续失败 5 次后会锁定 10 分钟
- `POST /api/auth/send-code` 现在会先按用途校验账号状态:登录 / 忘记密码要求账号已存在,注册要求账号尚未注册
- 当前登录页已临时放开成“一键进入”,账号密码和验证码输入暂时不作为拦截条件
- `POST /api/auth/send-code` 与固定验证码 `000000` 仍保留给注册 / 重置密码和后续认证收口,不作为当前登录页前置条件
- 新注册和重置密码现在使用 `scrypt` 哈希;历史 `sha256` 密码会在下一次密码登录时自动迁移
- 原生 Android 当前把 `ProjectForwardActivity / ThreadDetailActivity / OpsCenterActivity` 等复杂能力下沉到二级或更深层入口,不再把线程预算 / 转发 / 运维说明堆在主聊天页和一级我的页
- 原生 OTA 当前除了整包下载和系统安装器拉起,还会在关于页保留本地下载状态;离开关于页再回来时,仍能看到进行中 / 失败 / 待授权 / 可安装状态
- Android 本地 Gradle 验证当前必须串行执行,避免并发 `testDebugUnitTest / compileDebugJavaWithJavac / assembleDebug` 相互踩坏中间产物
- 当前默认最高管理员账号:`17600003315`
- 当前默认测试密码:`boss123456`
- 当前本机 Codex 节点 `mac-studio` 已绑定到 `17600003315`
- 主 Agent 对话当前真实执行链路是:`Boss Web -> master-agent task queue -> local-agent -> codex exec -> complete task -> project ledger`
- 主 Agent 同步等待窗口已调到 55 秒;如果本机 Codex 节点执行较慢,项目页也会通过 SSE 在任务完成后自动刷新出真实回复
- 服务器已经部署 `Postfix + Dovecot`,邮箱别名 `verify@boss.hyzq.net` / `no-reply@boss.hyzq.net` 当前会投递到本机 `bossmail` 邮箱
- 应用内 `POST /api/auth/send-code` 已经支持 email 模式,并可通过 `/opt/boss/.env.server` 切换;本轮已临时切到 email 模式验证成功,随后恢复默认 fixed
- 应用内 `GET /api/v1/user/ota` / `POST /api/v1/user/ota` / `GET /api/v1/user/ota/package` 现在已经支持 OTA 状态、检查更新、执行升级和 APK 包下载
- `GET /api/v1/app-logs` 现在已支持登录态下按 `deviceId / projectId / level / category / source / cursor` 查询日志分页
- 设备写接口 `POST /api/v1/app-logs``POST /api/v1/devices/[deviceId]/skills``POST /api/v1/workers/[workerId]/thread-context` 现在都要求有效设备 token 或匹配登录会话
- 当前认证仍是 MVP已有最小会话 Cookie但还没有刷新令牌、跨端会话治理、吊销审计和 CSRF 防护
- 聊天附件当前已支持真实上传、消息落账本、受保护下载和原生打开;默认存储后端为服务器文件存储
- 当前用户已可在 `我的 > 附件与存储` 切到阿里 OSS 私有桶,下载链会按附件快照生成签名地址,避免用户后续修改配置后旧附件失效
- 图片 / PDF / 文本默认自动进入主 Agent 附件分析;视频 / Office / 大文件默认手动触发
- 当前采用“极轻云 + 本地设备端”的路线,云端只承载 Web、轻 API 和状态文件
- 服务器侧主 Agent 对话能否返回真实大模型回复,依赖被绑定设备的 `local-agent` 在线并能执行 `codex exec`;服务器本身不直接持有主 GPT 会话