When children are still running, agent.await records the wait, closes the session (the tool call stays pending in the JSONL) and drive returns suspended. runAgent waits with waitForFact for the children to settle, the deadline, or cancellation, then reopens the session; agent.await is replay-safe, so resume replays it and the model gets the real result. Co-Authored-By: Claude Opus 5.5 <[email protected]>
UHD Media Tool
内部使用、Agent 自动化优先的媒体整理入库平台。需求基线见 media_automation_requirements_architecture_v0.7.md,v0.1 工程任务书见 docs/plan/00-first-version-plan.md。
快速启动
需要 Deno 2.9.7(锁定版本:curl -fsSL https://deno.land/install.sh | sh -s v2.9.7)和 Docker。不需要 Node.js / pnpm。
cp .env.example .env
deno task db:up # postgres:16-alpine,端口 55433
deno install # 按 deno.lock 安装依赖到 node_modules
deno task db:migrate
deno task dev # API http://localhost:4380 控制台 http://localhost:5180
提交前:deno task ci(typecheck:tsc 7.0.2 + deno check → biome → vitest → check:tokens → web 构建 + server 编译)。
前端冒烟(deno task test:web:smoke)
Playwright(playwright-core,用本机 Chromium)登录后逐个打开控制台全部路由(详情页从列表接口取第一条真实 ID),检查页面渲染出来、没有控制台报错 / 未捕获异常 / 4xx·5xx 的 API 请求,并逐页截图。不在 deno task ci 里,需要先起好后端与 web、并已初始化管理员:
deno task dev # 或单容器部署后直接用 4380
SMOKE_BASE_URL=http://127.0.0.1:5180 SMOKE_USER=<管理员> SMOKE_PASSWORD=<密码> deno task test:web:smoke
可选:SMOKE_OUT(截图目录,缺省 apps/web/test/screenshots/smoke,已 gitignore)、SMOKE_CHROMIUM(浏览器路径,缺省 /usr/bin/chromium)、SMOKE_SCREENSHOTS=0。全部通过退出 0,有失败 1,前置条件不满足 2。
部署
除 PostgreSQL 外全部在一个容器里(api + worker + worker:agent 三个进程 + web 静态,单端口 4380);compose 只有 app + postgres。
cp docker/compose.env.example .env # 填 SECRET_MASTER_KEY=$(openssl rand -hex 32)、POSTGRES_PASSWORD
docker compose up -d --build
docker compose logs app | grep 'setup token' # 首次初始化管理员
docker compose exec app umt backup # 备份到 /data/backups/<时间戳>/
- 应用数据卷
/data(Agent 会话、备份、导出);媒体库根与下载目录自行 bind mount,需对PUID:PGID(缺省 10001)可读写。 SECRET_MASTER_KEY不在备份里,和备份分开保管。- 详见 docs/runbook/deploy.md 与 docs/runbook/backup-restore.md。
更多见 docs/runbook/dev.md。
仓库结构
| 路径 | 职责 |
|---|---|
apps/web |
React Router 7 SPA 控制台,沿用 uhd_web 设计系统 |
apps/server |
Hono API(/api/v1)+ SSE + worker 入口;业务按 src/modules/<area>/ 分模块(见 apps/server/README.md) |
packages/contracts |
zod schema:API/事件/能力的唯一定义 |
packages/db |
Kysely 客户端、表类型与迁移 |
packages/domain |
纯业务逻辑,无 IO |
packages/mapping |
domain ↔ contracts 取值与结构映射(只依赖 domain + contracts) |
packages/adapters |
qB / RSS / 站点 / TMDB / Emby / 文件系统适配 |
packages/tasks |
持久任务与 outbox |
packages/agent |
Pi 接入与能力注册桥接 |
packages/testkit |
mock 服务与测试夹具 |
docs/adr |
架构决策记录 |
docs/design |
设计系统规范 |
docs/runbook |
运行手册 |
config/ |
tsc 7 用的 tsconfig 基座(根目录不放 tsconfig.json,否则 deno check 丢 Deno 全局) |
docker/ |
容器入口脚本、compose 环境变量示例 |
scripts/ |
备份 / 恢复脚本(镜像内 /app/scripts/) |
spikes/ |
独立兼容性验证(不属于 workspace) |
技术选型:Deno 2.9.7(锁定)+ TypeScript 7.0.2 strict,deno.json workspace(nodeModulesDir: auto,npm 依赖版本统一登记在根 deno.json 的 imports,deno.lock 锁定)。前端 Vite 7 + React Router 7 由 Deno 执行。决策见 ADR-004(取代 ADR-001)。