From 11ca2f01ffa3c9db5530a3e5d4a209f57f991b11 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 2 Oct 2026 16:08:09 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E4=B8=80=E9=94=AE=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E3=80=81=E5=8F=91=E5=B8=83=E8=84=9A=E6=9C=AC=E4=B8=8E=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E7=8E=AF=E5=A2=83=E7=BA=A6=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - deno task test:all(scripts/test-all.sh):逐包跑完再汇总,连不上测试库直接失败, web 用 Node 跑 vitest;deno task ci 改用它 - deno task release(scripts/release.sh):工作区不干净、CHANGELOG 无本版条目即拒绝; 打 tag、构建、只替换 app、核对健康接口版本 - deno task dev:up:起开发库并迁移到最新;开发 API 端口改 4390(4380 留给本机部署版) - CLAUDE.md:命令、提交与发布约定、文档放哪 Co-Authored-By: Claude Opus 5.5 --- .env.example | 2 +- CLAUDE.md | 41 + apps/web/vite.config.ts | 2 +- deno.json | 16 +- docs/design/agent-chat-review.md | 106 - docs/design/browser-ua-research.md | 37 - docs/design/de-ai-review.md | 372 -- docs/design/file-preview-research.md | 37 - docs/plan/00-first-version-plan.md | 227 - docs/plan/01-w1-review.md | 111 - docs/plan/02-w4-backlog.md | 18 - docs/plan/03-decoupling-audit.md | 31 - docs/plan/04-v0.1-acceptance.md | 249 - docs/plan/05-subscription-gap.md | 158 - docs/plan/06-file-manager-spec.md | 236 - docs/plan/07-v0.1-final-review.md | 323 - docs/plan/08-v0.2-closeout.md | 177 - docs/plan/09-visual-qa.md | 206 - docs/plan/10-v0.2.1-check.md | 106 - docs/plan/11-requirements-coverage.md | 313 - docs/plan/13-development-baseline.md | 188 - docs/plan/14-engineering-review.md | 107 - docs/plan/16-dependency-version-review.md | 145 - docs/plan/17-full-upgrade.md | 86 - docs/plan/18-organize-release.md | 126 - .../additional-metadata.json | 466 -- .../browser-audit.json | 353 -- .../deployed-containers.json | 51 - .../direct-dependencies.csv | 59 - .../2026-10-01-dependencies/locked-npm.csv | 634 -- .../upgrade-cleanup.json | 63 - .../upgrade-locks-and-direct-versions.json | 91 - .../upgrade-verification.json | 173 - .../workspace-audit.txt | 80 - docs/plan/{12-lessons.md => lessons.md} | 0 .../moviepilot-v3-comparison.md} | 0 docs/runbook/deploy.md | 13 +- docs/runbook/dev.md | 15 +- docs/spikes/deno-2.9.7.md | 196 - docs/spikes/w0b-openworkflow.md | 178 - docs/spikes/w0b-pi.md | 159 - scripts/release.sh | 63 + scripts/test-all.sh | 54 + spikes/.gitignore | 2 - spikes/README.md | 15 - spikes/deno/.dockerignore | 6 - spikes/deno/.gitignore | 2 - spikes/deno/Dockerfile | 20 - spikes/deno/apps/server/deno.json | 9 - spikes/deno/apps/server/src/db.ts | 50 - spikes/deno/apps/server/src/http.ts | 52 - spikes/deno/apps/server/src/log-logtape.ts | 12 - spikes/deno/apps/server/src/log-pino.ts | 32 - .../apps/server/src/migrations/0001_init.ts | 10 - .../apps/server/src/migrations/0002_index.ts | 5 - spikes/deno/apps/server/src/node-compat.ts | 32 - spikes/deno/apps/server/src/ow/cli.ts | 65 - spikes/deno/apps/server/src/ow/common.ts | 111 - spikes/deno/apps/server/src/ow/worker.ts | 14 - .../deno/apps/server/src/pi/abort-resume.ts | 61 - spikes/deno/apps/server/src/pi/common.ts | 84 - spikes/deno/apps/server/src/pi/fake-run.ts | 51 - .../deno/apps/server/test/node-apis.test.ts | 54 - .../deno/apps/server/test/node_apis_test.ts | 55 - spikes/deno/apps/server/vitest.config.ts | 6 - spikes/deno/deno.json | 55 - spikes/deno/deno.lock | 5200 ----------------- spikes/deno/logs/compile.txt | 17 - .../logs/compiled-ow-worker-bundle.out.txt | 4 - .../deno/logs/compiled-ow-worker-slim.out.txt | 4 - spikes/deno/logs/compiled-worker.out.txt | 7 - .../deno/logs/deno-check-real-repo-sloppy.txt | 7 - spikes/deno/logs/deno-check-real-repo.txt | 7 - spikes/deno/logs/deno-test.txt | 14 - spikes/deno/logs/docker.txt | 12 - spikes/deno/logs/hono-server.out.txt | 3 - spikes/deno/logs/hono-shutdown-0.out.txt | 3 - spikes/deno/logs/hono-shutdown-1.out.txt | 3 - spikes/deno/logs/hono-shutdown.txt | 2 - spikes/deno/logs/hono.txt | 21 - spikes/deno/logs/kysely-real-migrations.txt | 1 - spikes/deno/logs/kysely.txt | 14 - spikes/deno/logs/logtape.txt | 2 - spikes/deno/logs/node-compat.txt | 28 - spikes/deno/logs/ow-burst.txt | 2 - spikes/deno/logs/ow-happy.txt | 16 - spikes/deno/logs/ow-kill9.txt | 19 - spikes/deno/logs/ow-tables.txt | 5 - spikes/deno/logs/pi-abort.txt | 19 - spikes/deno/logs/pi-crash.txt | 5 - spikes/deno/logs/pi-fake-run.txt | 39 - spikes/deno/logs/pi-resume.txt | 15 - spikes/deno/logs/pino.txt | 7 - spikes/deno/logs/sloppy-fix.txt | 3 - spikes/deno/logs/tokens.txt | 4 - spikes/deno/logs/tsc7-real-repo.txt | 8 - spikes/deno/logs/tsc7-web.txt | 3 - spikes/deno/logs/typecheck-compare.txt | 11 - spikes/deno/logs/vitest-real-packages.txt | 12 - spikes/deno/logs/vitest-real-server.txt | 9 - spikes/deno/logs/vitest.txt | 27 - spikes/deno/logs/web-build.txt | 28 - spikes/deno/logs/web-dev-server.out.txt | 68 - spikes/deno/logs/web-dev.txt | 8 - spikes/deno/logs/web-vite-dev-server.out.txt | 7 - spikes/deno/logs/workerA.out.txt | 8 - spikes/deno/logs/workerA2.out.txt | 26 - spikes/deno/logs/workerB.out.txt | 22 - spikes/deno/packages/contracts/deno.json | 5 - spikes/deno/packages/contracts/package.json | 16 - spikes/deno/packages/contracts/src/agent.ts | 284 - spikes/deno/packages/contracts/src/api.ts | 783 --- spikes/deno/packages/contracts/src/assets.ts | 188 - .../packages/contracts/src/capabilities-io.ts | 218 - .../deno/packages/contracts/src/capability.ts | 280 - spikes/deno/packages/contracts/src/common.ts | 122 - spikes/deno/packages/contracts/src/content.ts | 129 - spikes/deno/packages/contracts/src/events.ts | 192 - .../deno/packages/contracts/src/execution.ts | 292 - .../deno/packages/contracts/src/identity.ts | 121 - spikes/deno/packages/contracts/src/index.ts | 16 - .../deno/packages/contracts/src/instances.ts | 161 - spikes/deno/packages/contracts/src/ops.ts | 194 - .../packages/contracts/src/organization.ts | 288 - spikes/deno/packages/contracts/src/policy.ts | 247 - .../deno/packages/contracts/src/settings.ts | 157 - spikes/deno/packages/contracts/src/sources.ts | 261 - spikes/deno/packages/contracts/tsconfig.json | 4 - spikes/deno/packages/x/deno.json | 5 - spikes/deno/packages/x/src/mod.ts | 20 - spikes/deno/tsconfig.base.json | 22 - spikes/deno/tsconfig.tsc.json | 20 - spikes/deno/web/README.md | 3 - spikes/deno/web/app/api/health.ts | 13 - spikes/deno/web/app/app.css | 1616 ----- .../app/components/console/api-key-dialog.tsx | 80 - .../app/components/console/empty-state.tsx | 35 - .../web/app/components/console/nav.test.ts | 15 - spikes/deno/web/app/components/console/nav.ts | 86 - .../app/components/console/page-header.tsx | 25 - .../app/components/console/status-badge.tsx | 37 - .../console/workspace-placeholder.tsx | 21 - spikes/deno/web/app/components/prism-leak.tsx | 10 - .../deno/web/app/components/theme-toggle.tsx | 57 - .../web/app/components/ui/alert-dialog.tsx | 160 - spikes/deno/web/app/components/ui/avatar.tsx | 89 - spikes/deno/web/app/components/ui/badge.tsx | 40 - .../deno/web/app/components/ui/breadcrumb.tsx | 92 - spikes/deno/web/app/components/ui/button.tsx | 68 - .../deno/web/app/components/ui/calendar.tsx | 47 - spikes/deno/web/app/components/ui/card.tsx | 56 - spikes/deno/web/app/components/ui/dialog.tsx | 135 - spikes/deno/web/app/components/ui/input.tsx | 21 - spikes/deno/web/app/components/ui/label.tsx | 21 - .../deno/web/app/components/ui/pagination.tsx | 154 - spikes/deno/web/app/components/ui/popover.tsx | 52 - spikes/deno/web/app/components/ui/select.tsx | 160 - .../deno/web/app/components/ui/separator.tsx | 26 - spikes/deno/web/app/components/ui/sheet.tsx | 105 - spikes/deno/web/app/components/ui/slider.tsx | 54 - spikes/deno/web/app/components/ui/sonner.tsx | 36 - spikes/deno/web/app/components/ui/switch.tsx | 24 - spikes/deno/web/app/globals.d.ts | 2 - spikes/deno/web/app/lib/api.ts | 107 - .../web/app/lib/design-tokens.generated.ts | 68 - spikes/deno/web/app/lib/utils.ts | 57 - spikes/deno/web/app/root.tsx | 85 - spikes/deno/web/app/routes.ts | 20 - spikes/deno/web/app/routes/console/agent.tsx | 31 - spikes/deno/web/app/routes/console/home.tsx | 58 - .../deno/web/app/routes/console/identity.tsx | 6 - spikes/deno/web/app/routes/console/inbox.tsx | 6 - spikes/deno/web/app/routes/console/layout.tsx | 208 - .../deno/web/app/routes/console/library.tsx | 6 - .../deno/web/app/routes/console/organize.tsx | 6 - .../web/app/routes/console/preferences.tsx | 6 - .../deno/web/app/routes/console/settings.tsx | 6 - spikes/deno/web/app/routes/console/sites.tsx | 6 - .../deno/web/app/routes/console/sources.tsx | 6 - .../web/app/routes/console/subscriptions.tsx | 6 - spikes/deno/web/app/routes/console/tasks.tsx | 6 - spikes/deno/web/app/routes/not-found.tsx | 19 - spikes/deno/web/components.json | 23 - spikes/deno/web/package.json | 47 - spikes/deno/web/react-router.config.ts | 6 - .../deno/web/scripts/check-design-tokens.sh | 47 - spikes/deno/web/scripts/gen-design-tokens.mjs | 39 - spikes/deno/web/tsconfig.json | 23 - spikes/deno/web/vite.config.ts | 65 - spikes/deno/web/vitest.config.ts | 8 - spikes/openworkflow/cli.ts | 64 - spikes/openworkflow/common.ts | 110 - spikes/openworkflow/worker.ts | 8 - spikes/package-lock.json | 1846 ------ spikes/package.json | 14 - spikes/pi/abort-resume.ts | 60 - spikes/pi/common.ts | 83 - spikes/pi/compaction.ts | 21 - spikes/pi/fake-run.ts | 50 - spikes/pi/provider-config.ts | 69 - 200 files changed, 191 insertions(+), 23061 deletions(-) create mode 100644 CLAUDE.md delete mode 100644 docs/design/agent-chat-review.md delete mode 100644 docs/design/browser-ua-research.md delete mode 100644 docs/design/de-ai-review.md delete mode 100644 docs/design/file-preview-research.md delete mode 100644 docs/plan/00-first-version-plan.md delete mode 100644 docs/plan/01-w1-review.md delete mode 100644 docs/plan/02-w4-backlog.md delete mode 100644 docs/plan/03-decoupling-audit.md delete mode 100644 docs/plan/04-v0.1-acceptance.md delete mode 100644 docs/plan/05-subscription-gap.md delete mode 100644 docs/plan/06-file-manager-spec.md delete mode 100644 docs/plan/07-v0.1-final-review.md delete mode 100644 docs/plan/08-v0.2-closeout.md delete mode 100644 docs/plan/09-visual-qa.md delete mode 100644 docs/plan/10-v0.2.1-check.md delete mode 100644 docs/plan/11-requirements-coverage.md delete mode 100644 docs/plan/13-development-baseline.md delete mode 100644 docs/plan/14-engineering-review.md delete mode 100644 docs/plan/16-dependency-version-review.md delete mode 100644 docs/plan/17-full-upgrade.md delete mode 100644 docs/plan/18-organize-release.md delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/additional-metadata.json delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/browser-audit.json delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/deployed-containers.json delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/direct-dependencies.csv delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/locked-npm.csv delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/upgrade-cleanup.json delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/upgrade-locks-and-direct-versions.json delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/upgrade-verification.json delete mode 100644 docs/plan/evidence/2026-10-01-dependencies/workspace-audit.txt rename docs/plan/{12-lessons.md => lessons.md} (100%) rename docs/{plan/15-moviepilot-v3-comparison.md => porting/moviepilot-v3-comparison.md} (100%) delete mode 100644 docs/spikes/deno-2.9.7.md delete mode 100644 docs/spikes/w0b-openworkflow.md delete mode 100644 docs/spikes/w0b-pi.md create mode 100644 scripts/release.sh create mode 100644 scripts/test-all.sh delete mode 100644 spikes/.gitignore delete mode 100644 spikes/README.md delete mode 100644 spikes/deno/.dockerignore delete mode 100644 spikes/deno/.gitignore delete mode 100644 spikes/deno/Dockerfile delete mode 100644 spikes/deno/apps/server/deno.json delete mode 100644 spikes/deno/apps/server/src/db.ts delete mode 100644 spikes/deno/apps/server/src/http.ts delete mode 100644 spikes/deno/apps/server/src/log-logtape.ts delete mode 100644 spikes/deno/apps/server/src/log-pino.ts delete mode 100644 spikes/deno/apps/server/src/migrations/0001_init.ts delete mode 100644 spikes/deno/apps/server/src/migrations/0002_index.ts delete mode 100644 spikes/deno/apps/server/src/node-compat.ts delete mode 100644 spikes/deno/apps/server/src/ow/cli.ts delete mode 100644 spikes/deno/apps/server/src/ow/common.ts delete mode 100644 spikes/deno/apps/server/src/ow/worker.ts delete mode 100644 spikes/deno/apps/server/src/pi/abort-resume.ts delete mode 100644 spikes/deno/apps/server/src/pi/common.ts delete mode 100644 spikes/deno/apps/server/src/pi/fake-run.ts delete mode 100644 spikes/deno/apps/server/test/node-apis.test.ts delete mode 100644 spikes/deno/apps/server/test/node_apis_test.ts delete mode 100644 spikes/deno/apps/server/vitest.config.ts delete mode 100644 spikes/deno/deno.json delete mode 100644 spikes/deno/deno.lock delete mode 100644 spikes/deno/logs/compile.txt delete mode 100644 spikes/deno/logs/compiled-ow-worker-bundle.out.txt delete mode 100644 spikes/deno/logs/compiled-ow-worker-slim.out.txt delete mode 100644 spikes/deno/logs/compiled-worker.out.txt delete mode 100644 spikes/deno/logs/deno-check-real-repo-sloppy.txt delete mode 100644 spikes/deno/logs/deno-check-real-repo.txt delete mode 100644 spikes/deno/logs/deno-test.txt delete mode 100644 spikes/deno/logs/docker.txt delete mode 100644 spikes/deno/logs/hono-server.out.txt delete mode 100644 spikes/deno/logs/hono-shutdown-0.out.txt delete mode 100644 spikes/deno/logs/hono-shutdown-1.out.txt delete mode 100644 spikes/deno/logs/hono-shutdown.txt delete mode 100644 spikes/deno/logs/hono.txt delete mode 100644 spikes/deno/logs/kysely-real-migrations.txt delete mode 100644 spikes/deno/logs/kysely.txt delete mode 100644 spikes/deno/logs/logtape.txt delete mode 100644 spikes/deno/logs/node-compat.txt delete mode 100644 spikes/deno/logs/ow-burst.txt delete mode 100644 spikes/deno/logs/ow-happy.txt delete mode 100644 spikes/deno/logs/ow-kill9.txt delete mode 100644 spikes/deno/logs/ow-tables.txt delete mode 100644 spikes/deno/logs/pi-abort.txt delete mode 100644 spikes/deno/logs/pi-crash.txt delete mode 100644 spikes/deno/logs/pi-fake-run.txt delete mode 100644 spikes/deno/logs/pi-resume.txt delete mode 100644 spikes/deno/logs/pino.txt delete mode 100644 spikes/deno/logs/sloppy-fix.txt delete mode 100644 spikes/deno/logs/tokens.txt delete mode 100644 spikes/deno/logs/tsc7-real-repo.txt delete mode 100644 spikes/deno/logs/tsc7-web.txt delete mode 100644 spikes/deno/logs/typecheck-compare.txt delete mode 100644 spikes/deno/logs/vitest-real-packages.txt delete mode 100644 spikes/deno/logs/vitest-real-server.txt delete mode 100644 spikes/deno/logs/vitest.txt delete mode 100644 spikes/deno/logs/web-build.txt delete mode 100644 spikes/deno/logs/web-dev-server.out.txt delete mode 100644 spikes/deno/logs/web-dev.txt delete mode 100644 spikes/deno/logs/web-vite-dev-server.out.txt delete mode 100644 spikes/deno/logs/workerA.out.txt delete mode 100644 spikes/deno/logs/workerA2.out.txt delete mode 100644 spikes/deno/logs/workerB.out.txt delete mode 100644 spikes/deno/packages/contracts/deno.json delete mode 100644 spikes/deno/packages/contracts/package.json delete mode 100644 spikes/deno/packages/contracts/src/agent.ts delete mode 100644 spikes/deno/packages/contracts/src/api.ts delete mode 100644 spikes/deno/packages/contracts/src/assets.ts delete mode 100644 spikes/deno/packages/contracts/src/capabilities-io.ts delete mode 100644 spikes/deno/packages/contracts/src/capability.ts delete mode 100644 spikes/deno/packages/contracts/src/common.ts delete mode 100644 spikes/deno/packages/contracts/src/content.ts delete mode 100644 spikes/deno/packages/contracts/src/events.ts delete mode 100644 spikes/deno/packages/contracts/src/execution.ts delete mode 100644 spikes/deno/packages/contracts/src/identity.ts delete mode 100644 spikes/deno/packages/contracts/src/index.ts delete mode 100644 spikes/deno/packages/contracts/src/instances.ts delete mode 100644 spikes/deno/packages/contracts/src/ops.ts delete mode 100644 spikes/deno/packages/contracts/src/organization.ts delete mode 100644 spikes/deno/packages/contracts/src/policy.ts delete mode 100644 spikes/deno/packages/contracts/src/settings.ts delete mode 100644 spikes/deno/packages/contracts/src/sources.ts delete mode 100644 spikes/deno/packages/contracts/tsconfig.json delete mode 100644 spikes/deno/packages/x/deno.json delete mode 100644 spikes/deno/packages/x/src/mod.ts delete mode 100644 spikes/deno/tsconfig.base.json delete mode 100644 spikes/deno/tsconfig.tsc.json delete mode 100644 spikes/deno/web/README.md delete mode 100644 spikes/deno/web/app/api/health.ts delete mode 100644 spikes/deno/web/app/app.css delete mode 100644 spikes/deno/web/app/components/console/api-key-dialog.tsx delete mode 100644 spikes/deno/web/app/components/console/empty-state.tsx delete mode 100644 spikes/deno/web/app/components/console/nav.test.ts delete mode 100644 spikes/deno/web/app/components/console/nav.ts delete mode 100644 spikes/deno/web/app/components/console/page-header.tsx delete mode 100644 spikes/deno/web/app/components/console/status-badge.tsx delete mode 100644 spikes/deno/web/app/components/console/workspace-placeholder.tsx delete mode 100644 spikes/deno/web/app/components/prism-leak.tsx delete mode 100644 spikes/deno/web/app/components/theme-toggle.tsx delete mode 100644 spikes/deno/web/app/components/ui/alert-dialog.tsx delete mode 100644 spikes/deno/web/app/components/ui/avatar.tsx delete mode 100644 spikes/deno/web/app/components/ui/badge.tsx delete mode 100644 spikes/deno/web/app/components/ui/breadcrumb.tsx delete mode 100644 spikes/deno/web/app/components/ui/button.tsx delete mode 100644 spikes/deno/web/app/components/ui/calendar.tsx delete mode 100644 spikes/deno/web/app/components/ui/card.tsx delete mode 100644 spikes/deno/web/app/components/ui/dialog.tsx delete mode 100644 spikes/deno/web/app/components/ui/input.tsx delete mode 100644 spikes/deno/web/app/components/ui/label.tsx delete mode 100644 spikes/deno/web/app/components/ui/pagination.tsx delete mode 100644 spikes/deno/web/app/components/ui/popover.tsx delete mode 100644 spikes/deno/web/app/components/ui/select.tsx delete mode 100644 spikes/deno/web/app/components/ui/separator.tsx delete mode 100644 spikes/deno/web/app/components/ui/sheet.tsx delete mode 100644 spikes/deno/web/app/components/ui/slider.tsx delete mode 100644 spikes/deno/web/app/components/ui/sonner.tsx delete mode 100644 spikes/deno/web/app/components/ui/switch.tsx delete mode 100644 spikes/deno/web/app/globals.d.ts delete mode 100644 spikes/deno/web/app/lib/api.ts delete mode 100644 spikes/deno/web/app/lib/design-tokens.generated.ts delete mode 100644 spikes/deno/web/app/lib/utils.ts delete mode 100644 spikes/deno/web/app/root.tsx delete mode 100644 spikes/deno/web/app/routes.ts delete mode 100644 spikes/deno/web/app/routes/console/agent.tsx delete mode 100644 spikes/deno/web/app/routes/console/home.tsx delete mode 100644 spikes/deno/web/app/routes/console/identity.tsx delete mode 100644 spikes/deno/web/app/routes/console/inbox.tsx delete mode 100644 spikes/deno/web/app/routes/console/layout.tsx delete mode 100644 spikes/deno/web/app/routes/console/library.tsx delete mode 100644 spikes/deno/web/app/routes/console/organize.tsx delete mode 100644 spikes/deno/web/app/routes/console/preferences.tsx delete mode 100644 spikes/deno/web/app/routes/console/settings.tsx delete mode 100644 spikes/deno/web/app/routes/console/sites.tsx delete mode 100644 spikes/deno/web/app/routes/console/sources.tsx delete mode 100644 spikes/deno/web/app/routes/console/subscriptions.tsx delete mode 100644 spikes/deno/web/app/routes/console/tasks.tsx delete mode 100644 spikes/deno/web/app/routes/not-found.tsx delete mode 100644 spikes/deno/web/components.json delete mode 100644 spikes/deno/web/package.json delete mode 100644 spikes/deno/web/react-router.config.ts delete mode 100755 spikes/deno/web/scripts/check-design-tokens.sh delete mode 100644 spikes/deno/web/scripts/gen-design-tokens.mjs delete mode 100644 spikes/deno/web/tsconfig.json delete mode 100644 spikes/deno/web/vite.config.ts delete mode 100644 spikes/deno/web/vitest.config.ts delete mode 100644 spikes/openworkflow/cli.ts delete mode 100644 spikes/openworkflow/common.ts delete mode 100644 spikes/openworkflow/worker.ts delete mode 100644 spikes/package-lock.json delete mode 100644 spikes/package.json delete mode 100644 spikes/pi/abort-resume.ts delete mode 100644 spikes/pi/common.ts delete mode 100644 spikes/pi/compaction.ts delete mode 100644 spikes/pi/fake-run.ts delete mode 100644 spikes/pi/provider-config.ts diff --git a/.env.example b/.env.example index 16644b25..d1f10785 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ # 复制为 .env 后按需修改(apps/server 与 packages/db 都会读取仓库根的 .env) -PORT=4380 +PORT=4390 DATABASE_URL=postgres://umt:umt@localhost:55433/umt # 凭证加密主密钥(32 字节以上随机串);与数据库备份分开保管 SECRET_MASTER_KEY=dev-only-change-me-dev-only-change-me diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..5c6ee1a7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,41 @@ +# UHD Media Tool + +影视自动化工具:站点 / RSS 获取 → 识别 → 下载(qB)→ 整理入库 → 刮削,带 Agent。后端 Deno + Hono + Kysely(PostgreSQL),前端 React Router 8 + Vite,同一个 workspace。业务逻辑以 MoviePilot v3 为参考(`docs/porting/`)。 + +面向团队内部使用,目前只有本机测试环境:**避免过度设计和过度防御**,只处理已确认会影响正常使用的问题。回复和文档用中文。 + +## 常用命令 + +```sh +deno task dev:up # 开发库(127.0.0.1:55433)+ 迁移到最新;拉代码后先跑 +deno task dev # API 4390 + web 5180(4380 是本机部署版,别占) +deno task test:all # 全量测试,逐包跑完汇总;连不上测试库直接失败 +deno task typecheck # tsc + deno check +deno task lint # biome;deno task fmt 会写文件,只对自己改的路径用 +deno task ci # 提交前完整检查(含 web 构建与编译产物自检) +deno task release # 测试环境发布,见下 +``` + +只改一个包时可在包目录跑 `deno run -A npm:vitest run <文件>`;web 包用 `../../node_modules/.bin/vitest run`(Node)。改迁移后跑 `deno task gen:types` 重新生成 `packages/db/src/types.ts`,contracts 枚举顺序与数据库保持一致(`packages/contracts/test/db-sync.test.ts` 会查)。 + +## 约定 + +- **先提交再部署**。发布只走 `deno task release`:工作区不干净直接拒绝;版本取根 `deno.json`(所有成员包同一版本);`CHANGELOG.md` 必须先有 `## [x.y.z]` 条目;脚本打 tag `vx.y.z`、构建镜像、只替换 app 容器(启动时自动迁移)、核对健康接口版本。测试环境不需要备份、在途任务清单、源码指纹等重流程。 +- 功能在分支上做,完成后合回 main;提交按功能拆,别把不相关的改动带进同一个提交。 +- 说"检查通过"只认 `deno task test:all` / `deno task ci` 的实际输出;跳过的用例不算通过。 +- 新增 Agent 能力要登记到某个 Skill(`packages/agent/skills/*/SKILL.md`)和能力地图(`packages/agent/src/prompt/layers/capabilities.ts`),否则 agent 测试会红。 +- 界面文案守 `docs/design/glossary.md` 的术语与标点(`deno task check:copy`);状态色只表示状态(`StatusBadge` 带圆点,别拿来显示数量)。 +- 主工作区不留常驻 dev 进程(`--watch` 会改写 `deno.lock`);构建前确认 `deno.lock` 没被改。 + +## 文档放哪 + +- 正在推进的计划与待办:`docs/plan/README.md`;做完的计划、验收、发布记录直接删除(git 历史可查),不留归档。 +- 版本变化:`CHANGELOG.md`,每版几行,不另写长篇发布记录。 +- 运维与使用:`docs/runbook/`;设计规范:`docs/design/`;架构决策:`docs/adr/`;MP 对照:`docs/porting/`。 +- 证据、截图、构建日志放 `.local/`(不进 git)。 +- 踩过的坑:`docs/plan/lessons.md`,派子代理或并行开发前先读。 + +## 参考 + +- MoviePilot 固定源码(只读):`/tmp/umt-moviepilot-v3-review-20261001`(v3.0.10-1,`0aa8571`),对照结论见 `docs/porting/moviepilot-v3-comparison.md`。 +- 本机部署:`docker compose --env-file .env.deploy …`,app 经 Caddy 暴露在 `https://:4380`,容器 HTTP 在 `127.0.0.1:4381`。 diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 93fbd88e..ab41fa32 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -49,7 +49,7 @@ function appVersion(): Plugin { export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), ""); - const apiTarget = env.VITE_API_TARGET || "http://localhost:4380"; + const apiTarget = env.VITE_API_TARGET || "http://localhost:4390"; return { plugins: [tailwindcss(), reactRouter(), appVersion()], diff --git a/deno.json b/deno.json index 79e7848e..c0d465b8 100644 --- a/deno.json +++ b/deno.json @@ -67,6 +67,10 @@ "dev:server": "cd apps/server && deno task dev", "dev:web": "cd apps/web && deno task dev", "db:up": "docker compose -f docker-compose.dev.yml up -d --wait", + "dev:up": { + "description": "开发环境就绪:起开发库(55433)并迁移到最新;之后 deno task dev(API 4390、web 5180)", + "command": "deno task db:up && deno task db:migrate" + }, "db:migrate": "deno run -A --env-file=.env packages/db/scripts/migrate.ts latest", "db:reset": "deno run -A --env-file=.env packages/db/scripts/migrate.ts reset", "gen:types": "deno run -A --env-file=.env packages/db/scripts/gen-types.ts", @@ -77,6 +81,10 @@ "lint": "deno run -A npm:@biomejs/biome check .", "fmt": "deno run -A npm:@biomejs/biome check --write .", "test": "deno task --members -j 1 test", + "test:all": { + "description": "全量测试:逐包跑完再汇总(不在首个失败处停),连不上测试库直接失败;web 用 Node 跑", + "command": "bash scripts/test-all.sh" + }, "test:web:smoke": { "description": "前端全页面冒烟(Playwright):需要已启动的后端 + web 与已初始化的管理员,见 README", "command": "deno run -A apps/web/scripts/smoke.mjs" @@ -91,7 +99,11 @@ "description": "编译产物自检:空环境跑 dist/umt-server --role preflight,确认完整模块图可加载(防 deno compile 漏嵌 npm 模块)", "command": "sh scripts/check-compiled-binary.sh" }, - "ci": "deno task typecheck && deno task lint && deno task test && deno task check:tokens && deno task check:copy && deno task build && deno task check:binary", - "gen:tokens": "cd apps/web && deno task gen:tokens" + "ci": "deno task typecheck && deno task lint && deno task test:all && deno task check:tokens && deno task check:copy && deno task build && deno task check:binary", + "gen:tokens": "cd apps/web && deno task gen:tokens", + "release": { + "description": "测试环境发布:要求工作区干净与 CHANGELOG 条目,打 tag、构建镜像、只替换 app、核对健康版本(scripts/release.sh)", + "command": "bash scripts/release.sh" + } } } diff --git a/docs/design/agent-chat-review.md b/docs/design/agent-chat-review.md deleted file mode 100644 index 7b496f1b..00000000 --- a/docs/design/agent-chat-review.md +++ /dev/null @@ -1,106 +0,0 @@ -# AGUI-3 智能体对话易用性审查 - -用户栈只读,看了 34 个已有会话中的 4 个:9883534f、31d16a1a(方案选择 + 审批)、174fea29、1a2dd4ee,没有发起新对话。截图在 `agui3/`,`d-` 是桌面,`m-` 是 390 宽。DEAI-2 已经在做的项不再重复。 - -## 1. 用户看到的信息与噪声 - -以 9883534f 为例,对话流一共 2223px,约 4 屏(d-02-run-simple-*): - -| 块 | 高度 | 判定 | -|---|---|---| -| 用户消息 | 63 | 需要 | -| 「Agent 20:06:42」回合头 | 11 | 删除 | -| 活动折叠行「6 次工具调用,思考 4 段 失败 1 更新步骤清单 → 列出站点…」×2 | 76 | 可折叠,要改成人话。「更新步骤清单」就是 agent.plan,和侧栏步骤重复 | -| 红色拒绝卡(4 个徽章 + 两行安全说明 + 调用 ID) | 213 | 缩成一行加按钮,约 40px | -| 最终回复正文 | 1225 | 需要。但 32% 的字符是函数名、字段名和 UUID(`site.list(includeDisabled=true)`、`062e5c51-…`),还有 6 列表格 | -| 「模型说的」卡:把正文**原样再显示一遍** | 328 | 删除 | -| 「系统核实的结果」卡 | 208 | 缩成一行 | - -**估算噪声占比约 49%**(约 1080/2223px)。其中最大的一块是正文里的技术字段,这要改 prompt,光改 UI 解决不了。对话流以外还有: - -- 目标出现 3 次(页头、气泡、列表选中行)。 -- 右侧栏:模型 ID、步骤备注里的工具原始输入(`site.list(inclu…`)、4 条预算进度条。 - -桌面 1440×900 下,对话可视区只有约 540×540,占屏幕 22%。手机上占 47%(m-02-*)。 - -## 2. 繁琐点 - -1. **同一个动作确认两次**(d-10、d-11):单选「A. 直接提交」→「选定」→ 又出「批准『提交下载』?」→「批准」。3 次点击、2 次确认。 -2. **没必要的方案选择**(174fea29):只问「看看有哪些新 4K」,也要在 3 个方案里选一个,因为开了「先看方案再执行」。 -3. **抽屉两层导航**(d-04 → d-06):「当前 / 历史」Tab,历史里打开会话后要「返回列表」;「新目标」按钮只在「当前」Tab 有。 -4. **看工具细节要点 3 层**(折叠行 → 工具卡 → 查看详情),看到的是 scope、幂等键、调用 ID。 -5. **历史难找**(m-05):子会话混在列表里(34 条中 11 条),等你处理的不置顶,窄栏里挤着 3 个下拉筛选。 -6. **结束后输入区 4 个控件**:输入框、「用同目标新建」、开关、续跑,下面还有一行说明(手机上也显示快捷键提示)。 - -## 3. 重设计 - -**对话流**:用户消息 → 一行进度状态 → 结论正文 → 一行实际结果。 - -- **进度行**:一个回合里的所有工具调用都聚合成一行(现在要连续 3 次以上才折叠,改成 1 次就折叠),用人话计数,例如「查了 1 个站点、2 份下载记录和媒体库 · 41 秒 ›」。 - - 展开后每步一行(「搜资源 → 2 条候选」);工具名、ID、思考过程放进「技术信息」。 -- **隐藏的调用**:`agent.plan` 和 `agent.propose_options` 不再作为工具调用出现在流里。 -- **被拒绝的调用**:不单独出卡片,在进度行里标「1 项没做」,正文下面补一行「没做:检测站点——需要你批准 [批准并重试]」。 - -**步骤清单**: - -- 去掉右侧栏,统一用顶部概况条「步骤 4/5 · 当前:核对下载任务」;备注只在失败时显示;预算和模型放进「技术信息」。 - -**方案卡**: - -- 每个方案做成一个按钮,**点一下就选定**。推荐项放第一位,并设为主按钮。 -- 风险折叠成「2 条风险 ›」。「都不要」降级成文字链接,点开后才出现原因输入框。 -- 只有真的存在分歧时才提问。「先看方案再执行」从开关改成输入框里的指令 `/先给方案`,只作用于这一次。 - -**审批卡**: - -- 只显示摘要和【批准】【拒绝】;UUID、payload hash、版本、到期时间收进「技术信息」。 -- 如果刚选定的方案里已经包含这个动作,**选定就等于批准**:服务端把选择绑定到同一个 planId + payloadHash,不再出第二张卡。 - -**输入区**: - -- 只留输入框和发送 / 停止按钮,空态显示 3 个快捷目标(入口页也要有)。 -- `/` 指令:`/先给方案`、`/重跑`。上下文显示成名称标签「沙丘:第二部 ×」,不再显示 `作品 · 74beab51…`。 - -**历史会话**: - -- 抽屉去掉 Tab,头部放「历史」图标(弹出最近 20 条)和「新对话」按钮。 -- 「等你处理」置顶,子会话收到父会话下面,筛选只留搜索框和「全部 / 等你处理 / 失败」。 - -参照物,只取交互思路: - -ChatGPT / Claude.ai 把工具调用折成一行;Cursor / Claude Code 每步一行可展开;MoviePilot 的工具调用是一行图标加文字,方案直接是按钮,支持斜杠指令(`AgentAssistantPanel.vue` 约 2574 行)。 - -## 4. 组件改动清单 - -| 优先级 | 文件 | 改动 | -|---|---|---| -| P0 | `apps/web/app/components/agent/agent-conversation.tsx` | 删掉 FinalReport 的双栏,换成一行实际结果;ActivityFold 改成 StepSummary(聚合、人话计数、技术信息);拒绝卡缩成一行;ToolCallCard 去掉徽章 / ID | -| P0 | `apps/web/app/components/agent/use-agent-stream.ts` | 过滤 agent.plan / propose_options 的工具调用 | -| P0 | `packages/agent/src/system-prompt.ts` | 规定汇报格式:第一句写结论;对象用名字,不写函数名、字段名、UUID;不超过 10 行;只有列举多个资源时才用表格 | -| P0 | `apps/web/app/components/agent/agent-interaction.tsx` | 方案卡改成一键选定,风险折叠;审批卡只留摘要,其余进技术信息 | -| P0 | `apps/web/app/components/agent/agent-run-panel.tsx` | 去掉右侧栏,统一用概况条;精简输入区工具栏和提示行 | -| P0 | `apps/web/app/routes/console/agent.$runId.tsx`、`agent.tsx` | 去掉页头的目标描述,对话占满;入口页加快捷目标和「等你处理」 | -| P1 | `apps/server/src/modules/agent/interaction.ts` | 选定方案即批准(绑定 planId + payloadHash,要补测试) | -| P1 | `packages/contracts/src/capability.ts`、`apps/server/src/modules/agent/capabilities-metadata.ts` | 每个能力加 `verb/noun`,用于人话计数,例如「查了 N 个站点」 | -| P1 | `apps/web/app/components/agent/agent-drawer.tsx`、`agent-store.ts` | 去掉 Tab,改成历史弹层加新对话按钮;上下文标签显示名称 | -| P1 | `apps/web/app/components/agent/agent-session-list.tsx` | 「等你处理」置顶、隐藏子会话、筛选改成三选一、行内信息精简 | -| P1 | `apps/web/app/components/agentui/prompt-input.tsx` | 斜杠指令菜单、上下文标签 | - -**和 DEAI-2 的冲突**:deai2 分支(4480fc3)已经改了上表的全部 `components/agent/*.tsx`、`agent-launcher.tsx`、`routes/console/agent*.tsx`、`capability.ts`、`capabilities-metadata.ts`、`interaction.ts`、`runner.ts`,目前只是文案替换,每个文件 2–14 行。**建议 DEAI-2 合并后再从新的 main 开 AGUI-3**。`system-prompt.ts`、`use-agent-stream.ts` 不冲突,可以先做。 - -## 5. 改前 / 改后示例 - -**例 1:工具步骤**(d-02-run-simple-top) - -- 改前:「6 次工具调用,思考 4 段 失败 1 更新步骤清单 → 列出站点 → 列出待处理…」,下面是 213px 的红色卡片:「服务端拒绝了『检测站点』 site.health_check ·执行 ·scope·admin ·低风险 ·幂等 ·授权校验未通过」,再加两行「有副作用的能力需要有效的持续授权…模型声称"用户已同意"无效…」。 -- 改后:「查了 1 个站点、下载记录和媒体库 · 1 项没做 ›」。正文下面一行:「没做:检测站点连通性,需要你批准 [批准并重试]」。 - -**例 2:结尾**(d-02-run-simple-bottom) - -- 改前:正文(带 `site.list(includeDisabled=true)` 和 UUID 表格)→ 「模型说的(未经核查)」原样重复一遍 → 「系统核实的结果」5 个徽章 + 4 个 0 + 来源说明。 -- 改后:「下载器和媒体服务器都还没接入,所以没法检查。站点『憨憨』正常,在做种 24 个。」再加一行「没有提交下载或整理 · 41 秒 · 约 $0.01 · 技术信息 ›」。 - -**例 3:方案选择 + 审批**(d-10、d-11) - -- 改前:单选框「A. 直接提交该 1080p 计划到下载器」,下面写「用已生成的草案计划 c062c84a-828d-…(槽位 37746be7、资源 0bd93cb0…)」加 2 条风险,点「选定」;之后又出「批准『提交下载』? 高风险 · 计划 c062c84a… · payload hash c201cb58… · r2 · 到期」,点「批准」。 -- 改后:卡片标题「《沙丘2》1080p 怎么收?」,下面三个按钮:【提交下载 · 12 GB(推荐)】【先修站点】【先不下】,底部有「2 条风险 ›」和「都不要…」。点第一个按钮就直接提交,不再出审批卡。 diff --git a/docs/design/browser-ua-research.md b/docs/design/browser-ua-research.md deleted file mode 100644 index c46437b4..00000000 --- a/docs/design/browser-ua-research.md +++ /dev/null @@ -1,37 +0,0 @@ -# BR-4 浏览器 UA / 指纹调研(只读) - -## 1. camofox 1.17.0 / Camoufox 现状 -- 内核 Camoufox 152.0.4-beta.28,camoufox-js 0.11.5。指纹在**浏览器进程启动时**生成(server.js `launchBrowserInstance` → `launchOptions({os: hostOS='linux', humanize, locale})`),BrowserForge 随机出 screen/WebGL/字体/硬件等,写进 `CAMOU_CONFIG_n` 环境变量;**同一进程内所有 context(每站点账号一个 profile)共用一套指纹**。 -- 浏览器空闲 5 分钟关闭、容器重启都会重新 launch → 除 UA 外的指纹每次重随机(日志已见 6 次 launch)。UA 由 BrowserForge 生成后把版本号替换为 152,OS 固定 Linux,推测为 `Mozilla/5.0 (X11; Linux x86_64; rv:152.0) Gecko/20100101 Firefox/152.0`(当前浏览器未运行,未能读实值)。 -- HTTP API 不能按会话指定 UA/os/screen/fingerprint;只有 env `CAMOFOX_LOCALE/TIMEZONE`(当前为空)。但有两个插件钩子可用:`browser:launching`(可改 launch options:传固定 `fingerprint`/`config`/`screen`/`window`)与 `session:creating`(可改 contextOptions,如 `userAgent`)。按 context 覆盖 UA 会与进程级的字体/WebGL/navigator 不一致(上游 issue 已记录),不建议。 -- 上游 camoufox-js 支持传入固定 `fingerprint` 或 `config` 字典 → **可在 umt 插件里持久化一套指纹 JSON,每次 launch 复用**。 - -## 2. 我们两端的 UA / Cookie 流向 -- HTTP 端:只有**登录(loginNexusPhp)与用户数据刷新**带 `acc.user_agent ?? settings.sites.userAgent`(Chrome 140/Windows)。**站点适配器(列表/搜索/详情/下载/healthCheck)`runtime.siteAdapter` 没传 `userAgent`,RSS fetcher 也没传** → 实际发的是 Deno 默认 UA(`Deno/2.9.7`)。同一账号 HTTP 端已经是两个 UA。 -- 浏览器端:打开会话时 `prepareCookies` 把账号 Cookie(或先 HTTP 账密登录得到的会话 Cookie)经 umt-cookies 注入 profile;关闭/释放/周期时 `syncCookies` 把站点域名下**全部 Cookie 原样回写**账号(`writeBrowserCookie`),HTTP 随即使用。 -- cf_clearance / __cf_bm 无任何特殊处理,会双向流动。当前 5 个 profile 未见 cf_ 类 Cookie;库里只有 1 个账号(hhanclub,Cookie 型,无 UA 覆盖,不走代理)。 -- IP:HTTP 端仅站点开“代理”才走 proxyUrl;浏览器容器有 `HTTP_PROXY=172.17.0.1:7891` 环境变量,Firefox 是否实际走它待核实 → 两端出口 IP 可能不同。 - -## 3. 站点绑定情况(公开资料) -- Cloudflare 官方:clearance“securely tied to the specific visitor and device … preventing reuse across machines”,不公开输入;社区普遍实测绑定 **UA + IP(+TLS 指纹)**。Deno/rustls 的 TLS 指纹与 Firefox 必然不同 → 即使 UA 一致,浏览器拿到的 cf_clearance 在 HTTP 端也不保证可用。 -- NexusPHP:c_secure_pass 等为 HttpOnly;经典实现仅在勾选“限制 IP”(securelogin)时把会话绑 IP,核心代码未见 UA 绑定。风险主要来自站点前置的 CF/WAF 和管理员的“多 UA/多 IP”风控。 -- 馒头:抓取走 API Key(x-api-key),与网页登录态无关(我们已不注入);网页 token 的设备/UA 绑定无权威公开资料,未证实。 -- 憨憨:NexusPHP 系,未找到 UA 绑定公开资料。 - -## 4. MoviePilot 做法 -- `site.ua or 全局 UA` 贯穿 HTTP 请求(全局 NORMAL_USER_AGENT 为 Mac Chrome 138)。 -- 仿真用 CloakBrowser(Chromium)或 FlareSolverr,新建 context 时传 `user_agent=site.ua`;FlareSolverr 返回的 userAgent 只在当次用。 -- 账密“更新 Cookie”在浏览器里登录后读 `navigator.userAgent`,**把 cookie 与 ua 一起写回站点**(cookie.py:397,site.py:1036)——即“UA 跟随取得 Cookie 的浏览器”。Chromium 内核 + Chrome UA,两端天然一致。 - -## 5. 结论与方案 -**推荐**:每账号一套“浏览器身份”(identity:UA + Camoufox 指纹 JSON),以浏览器为准,HTTP 全链路复用其 UA;不轮换。 -1. OS:建议统一 **Windows**(用户面最大、UA 最常见);但字体/WebGL 需 Camoufox 伪装,headed Linux 下渲染差异有暴露风险——或选 Linux 最真实。需用户决定。 -2. 因指纹是进程级,每账号不同指纹做不到;方案 A(推荐)全实例一套固定指纹,所有账号共用,插件在 `browser:launching` 读/首次生成并落盘;方案 B 每账号独立浏览器进程(资源翻倍,不推荐)。 -3. UA 版本跟随 Camoufox 大版本;升级镜像时插件保留指纹其余字段、只改版本号,并同步写回设置里的默认 UA。 -4. HTTP 端:siteAdapter、RSS、下载、登录统一带账号 UA;cf_clearance/__cf_bm 回写时剔除或标记“仅浏览器”。 - -**需改文件**:`docker/browser-desktop/root/opt/camofox/plugins/umt-cookies/index.js`(加 launching 钩子 + GET /umt/identity);`apps/server/src/modules/sources-identity/runtime.ts`(siteAdapter/RSS 传 UA,签名含 UA);`.../service/account.ts`、`credentials.ts`(回写时同步 UA、过滤 CF Cookie);`apps/server/src/modules/browser/service.ts`(会话开时读 identity);`packages/contracts/src/settings.ts`(默认 UA 改为 Firefox);迁移:`site_account` 增 `ua_source/identity_version`。 - -**风险与平滑迁移**:改 UA 通常不会让 NexusPHP Cookie 失效,但 CF 站点会立即要求重新过挑战。做法:不改已有账号的生效 UA,记录“待切换”;在下次重新登录 / 浏览器回写 Cookie 时原子地切换 Cookie+UA。Deno UA→浏览器 UA 的切换可立即做(风险低)。 - -**需用户决定**:OS 选 Windows 还是 Linux;全实例一套指纹是否可接受;是否允许浏览器 cf_clearance 给 HTTP 用(TLS 不同,大概率无效);是否统一浏览器与 HTTP 出口 IP。 diff --git a/docs/design/de-ai-review.md b/docs/design/de-ai-review.md deleted file mode 100644 index df733f38..00000000 --- a/docs/design/de-ai-review.md +++ /dev/null @@ -1,372 +0,0 @@ -# 去 AI 味、去工程味审查(DEAI-1) - -> 2026-09-29 · 只审查,不改代码。依据:`human-copy` 文案规范、用户品味清单、[glossary.md](glossary.md)、[console-ia.md](console-ia.md);对照 MoviePilot 前端 `src/locales/zh-CN.ts`。 -> 截图:登录 `https://127.0.0.1` 只读抓取(非 GET 的 `/api` 请求一律拦截,未碰站点搜索),存在 `apps/web/test/screenshots/deai/`(不进 git),下文用文件名前缀引用,如 `01-home`。 -> 缺口:库里没有订阅,订阅详情页无法截图,该页条目来自源码字符串(`routes/console/subscriptions.$id.tsx`、`components/subscriptions/*`)。 - -## 1. 总诊断 - -问题主要有五类,根源都是「界面是从数据模型和实现往外长出来的,没有先问用户此刻要什么」。 - -1. **数据模型直接当界面**。表名、状态码、枚举值原样上屏:`identity_unknown`、`blocked:target_exists`、`capability.invoke`、`tmdb:tv:90228`、`agent_run_event`、`r1`。整理记录、待处理、下载时间线、审计都有。 -2. **每个字段都想解释,解释的是实现而不是后果**。计划页 29 行说明里有「对照 MP 启动时的 clear_temp」「observation,按 created_at」「umt backup(宿主机 cron 调用)」;设置页讲哨兵文件 `.uhd-root`、负缓存、三个进程共用。用户看不懂,看懂了也做不了决定。 -3. **为可审计而堆证据**。Agent 会话一屏里同时有「模型说的(未经核查)」「仅供参考,不作为完成依据」「系统核实的结果」、5 个状态徽章、4 个 0 计数、数据来源说明、token 数和四位小数的美元费用。可信度是靠一句话和一个链接建立的,不是靠把账本摊开。 -4. **内部概念名直接露给用户**。版本目标、内容单元、临时单元、资产、外部身份、库根、纳管、快照、候选、修订、草案、抑制记录、持续授权、幂等。MP 用「洗版」「已入库 / 缺失」「媒体库目录」「整理」「识别」这类用户早就会说的词。 -5. **同一件事多种说法、多重信号**。「身份歧义 / 识别有歧义 / 无法确定作品」「RSS 订阅 / 来源健康 / Feed」「媒体概览 / 媒体库」「整理冲突 / 路径冲突 / target_exists」;「自动化运行中」同时用播放图标、绿点徽章「总开关开」和一句口号表达。 - -另有一个事实性问题:首页写「0 个订阅在追踪,自动收录、下载和整理」,数字为 0 时后半句是空承诺。 - -## 2. 术语对照表 - -「界面」一列:**显示** = 默认视图可以出现;**详情** = 只在详情页 / 折叠区 / 高级设置出现;**隐藏** = 只在代码、日志、给模型的提示里。 - -| 当前用词 | 用户视角的说法(参考 MP / 常识) | 界面 | 说明 | -| --- | --- | --- | --- | -| 版本目标 / Slot | 「想要的版本」;升级动作沿用 MP 的「洗版」 | 显示(改名后) | 首页「版本目标满足率」改「想要的版本已到齐 x / y」;列名「版本目标」→「版本」。**需拍板**,见 §5.4 | -| 资源(SourceRelease) | 资源 | 显示 | 保留,和 MP 一致 | -| 候选 | 不单独命名;说「可下载的资源」「选一个下载」 | 隐藏 | 「候选被选中后生成计划」这种句子直接删 | -| 观察(observation) | 不出现 | 隐藏 | 目前出现在设置「Feed 观察」、计划页「观察记录清理」、下载时间线「观察 · 无」 | -| 内容单元 | 季 / 集 | 隐藏 | 作品详情面板标题「内容单元」→「季与集」 | -| 临时单元 | 「未确认的集」或不提示 | 详情 | 徽章「临时单元」→「编号待确认」 | -| 资产 / 资产位置 | 文件 / 已入库文件 | 显示为「文件」 | 首页「资产 5 已入库视频」→「已入库文件 5」 | -| 运行 / run / 引擎运行 | 任务(用户侧);引擎步骤只在详情折叠区 | 详情 | 「未关联业务对象 · ce28d777」这种行默认不进任务列表 | -| 租约 / 控制权 / 接管(浏览器) | 「你在操作」/「交还给 Agent」 | 显示(按钮) | 「租约」一词不出现 | -| 纳管 / 接管(下载器) | 「由本工具管理」;筛选叫「来源:本工具 / 其他」 | 显示(改名后) | 下载列表每行的「接管」徽章删掉,只在不是本工具管理的行标「外部任务」 | -| 证据 / 原始证据 / 证据等级 | 「详情」「依据」 | 详情 | 待处理的「原始证据」→「详细信息」;身份的「证据 人工确认 · 校验通过 · r1」→「你确认的」/「自动匹配」 | -| 能力 / capability | 「Agent 能做的事」;具体项用动作名(查作品、提交下载) | 详情 | 审计里的 `capability.invoke` / `capability.denied` 显示为「Agent 查询 · 订阅列表」「Agent 被拒绝 · 检测站点健康」 | -| Agent 上游 / 上游 | 模型服务 / 模型 | 显示(改名后) | MP 叫「AI Agent / 上游 provider」也不好;「上游登录刷新」每 10 分钟刷屏,见 §3.2。**需拍板** | -| 巡检 | 巡检 | 显示 | 可保留;说明里去掉「能力白名单」 | -| 待识别 / 待识别池 | 未识别 | 显示 | MP 用「未识别到媒体信息」。「池」字去掉(console-ia §6.4 早已记为遗留) | -| 身份 / 外部身份 | 「TMDB / IMDb 编号」;动作叫「识别」「改匹配」 | 详情 | 「身份歧义」统一成「识别有歧义」;`tmdb:tv:90228` 显示为「TMDB 90228」链接 | -| TMDB 映射 | 匹配的 TMDB 条目 | 详情 | | -| 持续授权 | 「允许 Agent 自动执行 xx」 | 详情 | 只在 Agent 设置和巡检编辑框出现,不带 ID 前缀 | -| 审批 | 批准 / 拒绝 | 显示 | 保留;「会话内审批有效期」→「等你批准的最长时间」 | -| 幂等 / 幂等键 | 不出现 | 隐藏 | 工具调用卡片上的「幂等」徽章删,幂等键进审计详情 | -| 整理记录 | 整理记录 | 显示 | 与 MP「媒体整理 / 历史记录」一致,保留 | -| 库根 | 媒体库目录 | 显示(改名后) | MP 叫「媒体库目录」;「实际路径与库根」→「文件位置」 | -| 登记目录 | 不单独命名,就是「目录」 | 隐藏 | 文件管理左栏已经按「下载目录 / 媒体库」分组,不需要这个词 | -| 哨兵 / 哨兵文件 | 「目录检查」;失败时说「目录不可访问或未挂载」 | 详情 | 按钮「检查哨兵」→「检查目录」 | -| 快照 | 「站点最新资源」/「抓取」 | 详情 | 站点卡「快照 22 分钟前」→「资源更新于 22 分钟前」;「实时补查」→「去站点搜」 | -| 账本 / 本地账本 | 不出现 | 隐藏 | 「本地账本:作品、版本目标、资产与外部身份」整句删 | -| 建档 / 已建档 | 「加入媒体库」/「已在库中,未下载」 | 显示(改名后) | 「建档不订阅」→「只加入媒体库」 | -| 修订 r1 / 草案 / 策略版本 | 「最后修改于…」;草案叫「未启用」 | 详情 | 列表的「修订」列删 | -| 抑制记录 | 「已忽略的资源」 | 显示(改名后) | 规则页签名 | -| 收录策略 | 「自动收新作品」 | 显示(改名后) | 规则页签;只在开启新作品自动收录时有意义 | -| 缓存卷 / 硬阈值 / 恢复水位 | 下载盘 / 暂停线 / 恢复线 | 显示(改名后) | 「保留期锁定 287.92 MB」→「做种保留中 288 MB」 | -| 进程 / 心跳 / SSE / 事件循环延迟 | 不出现在首页 | 详情 | 只在运行状态页的「高级」折叠区 | - -## 3. 页面级问题 - -格式:截图 · 现象(原文) · 为什么 · 改成。 - -### 3.1 首页 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 01-home | 横幅「自动化运行中」+ 绿点徽章「总开关开」+ 播放图标 +「0 个订阅在追踪,自动收录、下载和整理。」 | 三个信号说一件事;0 订阅配口号是空承诺 | 一行:「自动化已开启 · 0 个订阅」+ 右侧「暂停」。订阅为 0 时换成「还没有订阅。去搜索添加」 | -| 01-home | 首页有「只读对账」开关 | 恢复备份才用的运维开关,放首页既吓人又易误点 | 移到设置 → 自动化 → 高级;首页只在它开启时显示一条警告「只读模式:不会自动下载和整理」 | -| 01-home | 「排队 0 · 下载中 0 · 无进展 0 · 入库中 0」「满足 0 / 0 · 需关注 0 · 下载中 0」「新计划 0 · 提交下载 4 · 入库文件 5 · 升级 0」 | 0 值全部铺开,读者要自己找非零项 | 只显示非零项;全为 0 时不显示这一行 | -| 01-home | 「版本目标满足率 —」 | 内部指标名;分母为 0 时显示横线等于没说 | 分母为 0 时整块隐藏;有数据时「想要的版本已到齐 12 / 15」 | -| 01-home | 「最近完成 / 失败」6 行全是绿色「完成」徽章,副标题「处理待处理事项」「核验入库」 | 徽章泛滥;副标题是工作流名 | 只列失败和入库完成;成功不加徽章;副标题写结果「已入库」「识别失败」 | -| 01-home | 「缓存与保留:阈值 90% / 恢复 85% · 在途 0 B · 可清理 0 B · 保留期锁定 287.92 MB」 | 5 个运维参数挤一行 | 「下载盘 36% 已用 · 剩 1 TB」,细节进下载面板 | -| 01-home | 「运行状态:进程 3 在线 · 待执行 0 · 24 小时失败率 0.2% · 数据库 5.3 毫秒」 | 首页给普通用户看数据库延迟 | 正常时只显示「运行正常」一行或不显示;异常时显示问题本身 | -| 01-home | 「近 7 天 $0.0191」 | 四位小数制造精确感 | 「近 7 天 $0.02」,不足一分写「< $0.01」 | - -### 3.2 任务 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 02-tasks | 页描述「每次运行都是一条任务,不论定时、事件、手动还是 Agent 触发。」 | 解释数据模型,排比式列举 | 删,或「最近处理了什么、有没有失败」 | -| 02-tasks | 「评估候选 · 未关联业务对象 · ce28d777」「识别资源 · 未关联业务对象 · 37b8a16c」成片出现 | 内部步骤和短 ID 占满列表 | 默认隐藏无业务对象的运行,筛选里提供「显示系统任务」 | -| 02-tasks | 「上游登录刷新」每 10 分钟一条 | 后台保活刷屏 | 维护类定时任务成功时不进任务列表,只记在计划页 | -| 02-tasks | 耗时「20 毫秒」「206 毫秒」 | 毫秒级精度对用户无意义 | 小于 1 秒写「< 1 秒」 | -| 02b-tasks-failed | 标题「下载 c062c84a」,「未开始 · 19 小时前」 | 用 ID 当标题 | 用作品名 + 资源名;无作品时用资源标题 | -| 02-tasks | 行副标题「核验入库 · 下载」「处理待处理事项 · 待处理事项」 | 工作流名 + 对象类型,重复且拗口 | 只留一个:「入库检查」「识别」 | - -### 3.3 计划 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 03-schedules | 「图片缓存清理:删除超过保留天数的图片代理缓存文件(对照 MP 启动时的 clear_temp)」 | 实现备忘写进界面 | 「删除过期的海报缓存」 | -| 03-schedules | 「观察记录清理 … (observation,按 created_at)」「SSE 事件清理 … (sse_event,按 at;发布方另按条数裁剪)」「审计清理 …(audit_event…)」 | 表名、字段名上屏 | 把 18 项「维护」合并成一行「数据清理(9 项)」,展开后每项一句人话 | -| 03-schedules | 「备份:…目前用 umt backup(宿主机 cron 调用),未接入调度」,状态「未运行 · 未配置」 | 开发状态说明;一个不能用的开关占一行 | 未接入就不列;或只在运行状态页写「备份:上次 2026-09-28」 | -| 03-schedules | 「统计信息更新:对全库执行 ANALYZE,刷新查询规划用的统计信息」 | 数据库运维 | 放进「数据清理」组,文案「数据库维护」 | -| 03-schedules | 「到期重评:到了重评时间的收录位重新评估(忙时延后的发布、定时)」 | 「收录位」是术语表外的第三个 Slot 名 | 「重新检查等待中的资源」 | -| 03b-schedules-checks | 巡检卡片直接显示目标模板「巡检待处理({{now}}):有 {{openDecisions}} 条…」 | 模板变量上屏 | 卡片只显示一句用途「检查待处理并给建议」,模板进编辑框 | -| 03b-schedules-checks | 每张卡有「能力」6 个标签 + 3、预算、上游、触发条件、间隔、下次、每次费用、最近结果、最近会话 9 项 | 字段全铺 | 默认:名称、开关、间隔、上次结果与费用;其余进编辑框 | - -### 3.4 Agent 会话与抽屉 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 04b-agent-run | 「模型说的(未经核查)」+「仅供参考,不作为完成依据。」+「系统核实的结果」 | 同一个免责声明说了三遍,措辞防御 | 回复区不加标题;下面一行「实际结果:没有提交下载或整理」,有动作时列出链接 | -| 04b-agent-run | 徽章「没有产生业务动作」「运行已完成」「工具成功 7」「失败 1」「被拒绝 1」+ 四个 0 计数 + 「取自下载计划、下载任务和整理记录(生成于 …)。「已提交」指已进入下载器,整理成功才算入库。」 | 为可审计堆证据;0 计数和数据来源说明是噪音 | 只在有动作时显示计数;工具统计进「步骤」折叠区;数据来源说明删 | -| 04b-agent-run | 步骤列表显示 `site.list(inclu…`、`site.health_c…` | 工具函数名上屏 | 步骤只写人话,工具名进展开详情 | -| 04b-agent-run | 右栏「预算与用量:工具调用 9 · token 320.7k · 时长 41s · 费用(估算)$0.014」;头部「opencode-go/deepseek-v4.1-flash」 | token、模型 ID 对普通用户无意义 | 默认只显示「费用约 $0.01 · 41 秒」,token 与模型进「详情」 | -| 04-agent | 会话列表标题是原始提示词:「在浏览器会话 16be7338-… 上直接调用一次 browser.solve_challenge,参数:…」 | UUID、JSON 当标题 | 标题取模型生成的短摘要或截断到第一句;子会话默认折叠在父会话下 | -| 04-agent / 04c | 「交代目标,边做边汇报」出现在侧栏按钮、悬浮按钮;抽屉又写「交代目标,Agent 在授权范围内执行并汇报。(Ctrl+J 开关,Esc 关闭)」,输入框下再写「Agent 列出步骤后直接执行…Enter 发送,Shift+Enter 换行。」 | 口号式对仗重复 3 处;快捷键提示重复 4 处 | 侧栏按钮只写「Agent」+ 快捷键;删悬浮按钮或侧栏按钮其一;抽屉只保留 placeholder「例如:把沙丘:第二部的 4K 收进来」 | -| 04c | 收起按钮是带渐变描边的胶囊「收起 Ctrl+J / Esc 关闭」 | 渐变描边 + 发光,和侧栏、悬浮按钮三处同款 | 普通关闭按钮 × | -| agent-conversation.tsx | 「有副作用的能力需要有效的持续授权或单次审批,由服务端在执行前核对,模型声称"用户已同意"无效。」;工具卡片「幂等」徽章 | 安全设计说明写给用户 | 拒绝时只说「未执行:需要你批准」+「批准」按钮 | - -### 3.5 站点与站点详情 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 05-sites | 页描述「凭证、账号数据和健康状态;点站点名看资源、快照与 Feed」 | 列内容 + 操作指引,都能从界面看出 | 删 | -| 05-sites | 卡片:「健康检测 正常 · 1201 ms · 4 小时前」「快照 22 分钟前」「限流 默认」 | 毫秒延迟、限流、快照是运维字段 | 卡片只留账号数据 + 一行状态「正常 · 资源更新于 22 分钟前」;异常时写原因 | -| 05-sites | 徽章「账号正常」「Cookie」「VIP」 | 登录方式不需要徽章 | 只留「VIP」这类等级;状态正常不加徽章,异常才标 | -| 05b-site-overview | 「快照每 1 小时 1 页 · 健康检测每 6 小时 · 详情缓存 24 小时」「近 24 小时请求 22 次」「代理 不使用」 | 配置回显 | 放进「编辑站点」 | -| 05b / 03 | 站点页「健康检测每 6 小时」,计划页「站点健康检测 每 1 小时」 | 两个数字说的是扫描间隔和单站间隔,用户看到的是矛盾 | 计划页写「每 1 小时检查一次哪些站点到期」或直接不在计划页列出 | -| 05c-site-resources | 每行资源都有「已识别,无版本目标」 | 默认情况重复 50 次 | 只标需要注意的:「未识别」「已在库中」「可洗版」 | -| 05c-site-resources | 按钮「快照」「实时补查」,角落「近 24 小时请求站点 22 次」 | 实现术语 | 「刷新」「去站点搜」;请求次数进站点详情 | -| 05e-site-accounts | 账号页的「Passkey」(站点 RSS 密钥)与账户设置里的「Passkey」(登录用生物识别)同名 | 同名两物 | 站点这边写「站点 Passkey(RSS 与下载链接用)」,账户那边写「通行密钥(Passkey)」 | - -### 3.6 RSS 订阅 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 06-rss | 侧栏叫「RSS 订阅」,页标题叫「来源健康」,表格节标题叫「FEED」,术语表叫「Feed」 | 一物三名 | 全站统一「RSS」;页标题「RSS」,节标题「RSS 地址」 | -| 06-rss | 页描述「单个站点的快照、Feed 和账号在站点页管理。」 | 用说明文字修补 IA | 删;站点名本身可点 | -| 06-rss | 「站点」表格与站点页重复(健康、账号、最近快照) | 同一信息两处 | 本页只列 RSS;站点健康只在站点页 | -| 06-rss | 列「用途:通用」 | 只有一个取值时是噪音 | 只有非通用时显示 | - -### 3.7 订阅与订阅详情(源码) - -| 位置 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 07-subscriptions | 筛选栏 11 组(类型、批量、状态 6 值、站点、规则组、来源、洗版、排序),库里 0 条订阅时全部显示 | 空库也铺满控件 | 0 条时只显示空态和「新建订阅」 | -| 07-subscriptions | 空态「从媒体库、搜索或 Agent 添加,也可以点「新建订阅」。」 | 列举三个入口 | 「还没有订阅。」+ 按钮「新建订阅」 | -| coverage-matrix.tsx | 「临时单元」「还没有正式的内容单元」「按版本目标逐集对比」 | 内部概念 | 「编号待确认」「按版本逐集查看」 | -| subscriptions.$id.tsx | 「按选择顺序串联;不选 = 订阅默认规则组。版本目标自己的规则组另算」「空 = 24;0 = 关」「空 = 按 TMDB;不锁定时只升不降」 | 规则引擎语义写成等式 | 字段默认值直接填进输入框作为 placeholder;规则组说明只留「不选时用默认规则组」 | -| subscriptions.$id.tsx | 「季建好后不能改;要换季就新建订阅」 | 好文案 | 保留 | - -### 3.8 规则 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 08-rules | 页描述「规则组决定哪些资源能下载、同一作品优先挑哪个。收录策略决定哪些新作品自动收录。」 | 两句对仗定义 | 删;页签名本身要自解释 | -| 08-rules | 页签「规则组 / 自定义条件 / 默认值 / 收录策略 / 抑制记录」 | 五个里三个是内部名 | 「规则组 / 自定义条件 / 默认规则 / 自动收新作品 / 已忽略」 | -| 08-rules | 列「修订 r1」「引用 默认链」 | 版本号与引用关系 | 删「修订」列;「引用」写「订阅默认」这种具体用途 | -| 08b-rules-atoms | 13 个关键字各写「不支持,规则串里出现会报错」;标题「对齐 MoviePilot;判定依据按解析字段优先」 | 列出不支持的东西;实现备忘 | 不支持的关键字不列,或合并为一行「音乐相关关键字暂不支持」;副标题删 | -| 08c-rules-defaults | 「链上的组按顺序串联,任一组拒绝即拒绝,优先级取最后一个带层的组。」 | 算法描述 | 「按顺序检查,任一组不通过就不下载。」「带层」概念不出现 | -| 08d-rules-policies | 策略名「AGENT-REAL 最小收录策略(测试)」,按钮「新建策略草案」「基于 r1 新建草案」 | 测试数据留在用户栈;草案 / 发布模型外露 | 清理测试数据(数据问题,另开);按钮「新建」「复制并修改」 | - -### 3.9 下载面板 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 09-downloads | 页描述「阈值暂停不能手动绕过;无进展只记录,不自动换源。」 | 两条否定式声明当首屏第一句 | 删;在暂停的任务行上写「磁盘超过 90%,已暂停」 | -| 09-downloads | 「qB 测试 36.2% · 604.4 GB / 1.6 TB · 硬阈值 90% / 恢复 85% · 在途 0 B · 预留 0 B · 可清理 0 B · 保留锁定 287.9 MB」 | 7 个数一排 | 进度条 + 「已用 604 GB / 1.6 TB」;其余进「详情」 | -| 09-downloads | 每行徽章「接管」,筛选「纳管」 | 内部概念,且每行都一样 | 删徽章;筛选「来源:本工具 / 其他」 | -| 09-downloads | Interstellar 行状态「下载完成」,但整理两次失败 | 状态没反映真实问题 | 状态列写「入库失败:目标已存在」并链到待处理 | -| 09c-download-detail | 时间线「0/0 文件成功 · identity_unknown」「blocked:target_exists」 | 错误码原样上屏 | 「没有识别出作品」「媒体库里已有同名文件」 | -| 09c-download-detail | 时间线筛选「观察 · 无 / 计划 · 无 / 下载 · 2 / 整理 · 2 / Agent · 无 / 任务 · 2」,标题「业务时间线」 | 空类别也列;「业务」是开发词 | 标题「经过」;只显示有记录的类别 | -| 09c-download-detail | 「torrent hash 31090bf…」直接列在概况 | 技术信息占首屏 | 进「详情」折叠 | -| 09b-download-plans | 「候选被选中后生成计划,同时预留版本目标、空间与预算。」 | 机制说明 | 删;空态「还没有下载计划」 | - -### 3.10 整理记录 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 10-organize | 失败原因列显示 `identity_unknown`、`blocked:target_exists` | 服务端把错误码当 message 返回(`organize.ts:393`、`:641`),前端原样显示 | 服务端给中文 message;前端已有映射 `organize-wizard/model.ts` 的 `target_exists: "目标已存在"`,统一复用 | -| 10-organize | 「未关联作品 · — · 失败 · 复制 0/0」连续 4 行 | 0 文件的失败记录 | 合并为一行「4 次未识别,未整理」或只在待处理出现 | -| 10b-organize-detail | 「变更游标 35」「记录 ID」「任务 ID」「执行进程本地」「未知或未授权」 | 同步接口字段、内部 ID | 进「技术信息」折叠;「未知或未授权」改「未整理」 | -| 10b-organize-detail | 按钮「让 Agent 排查」 | 可以 | 保留 | -| 10-organize | 页描述「每次整理的前后路径与逐文件结果,自动和手动整理都记在这里。」 | 能看出来 | 删 | - -### 3.11 文件管理 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 11-files | 左栏下载目录与媒体库各带「正常」徽章和「剩余 1 TB」,底部又一处「剩余 1 TB」 | 同一信息两次;正常态徽章 | 正常不标;剩余空间只在底栏 | -| 11-files | 行摘要「1 视频 · 0 已登记」 | 「已登记」是内部状态 | 「1 个视频 · 未入库」 | -| 11-files | 筛选「临时文件」「已登记」 | 同上 | 「未完成下载」「已入库」 | -| 库根设置 | 「没有可写的库根。在设置里把库根设为纳管后再选。」(`dir-picker.tsx`) | 双重术语 | 「没有可写入的媒体库目录。去设置添加」 | - -### 3.12 媒体概览与作品详情 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 12-library | 侧栏「媒体概览」,详情页面包屑「媒体库」 | 一物两名 | 统一「媒体库」(MP 同) | -| 12-library | 描述「本地账本:作品、版本目标、资产与外部身份。自动匹配不覆盖人工锁定的外部身份。」 | 比喻 + 规则声明 | 删 | -| 12-library | 页签「作品 / 待识别 / 外部身份 / 别名」 | 后两个是维护工具 | 默认只留「作品 / 未识别」;外部身份、别名进作品详情 | -| 12c-library-identities | 行「tmdb:tv:90228 · 已确认 · 人工确认 · 校验通过 · r1 · 23 分钟前」 | 键值串 + 三个同义状态 | 「TMDB 90228 · 你确认的」 | -| 12a-library-unidentified | 原因「未命中订阅」,列「尝试 1 次 · 26 分钟前」「下次复查 24 小时后」 | 未命中订阅不是问题,不该叫原因 | 这类资源默认不进「未识别」,只放真正需要人处理的 | -| 12b-library-detail | 标题下直接显示 UUID `d1fd8828-…`;「以本地 ID 为准,外部身份可修改」 | 内部 ID 与实现声明 | UUID 进「更多 → 复制 ID」;说明删 | -| 12b-library-detail | 「字段来源与锁:锁定的字段刷新时不变」,每字段「来源 TMDB · zh-CN · 26 分钟前 · 候选:TMDB「2014」」 | 字段溯源铺满 | 默认折叠为「元数据来自 TMDB · 更新于 26 分钟前 · 编辑」 | -| 12b-library-detail | 别名一次铺出 80 多种语言 | 无筛选的数据倾倒 | 只显示中英文与用户添加的,其余「+83」 | -| 12b-library-detail | 「实际路径与库根:路径绑定建立后不随译名变化」,每个文件「主位置 · 可访问 · 已核验」 | 同上 | 「文件」一节,每行路径 + 大小;异常才标 | - -### 3.13 设置(9 区) - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 13-settings-automation | 「存储预算」「流水数据保留」「缓存有效期」三组 13 个天数 / GB 字段,含「Feed 观察」「实时事件」「进程心跳(小时)」「能力调用统计」「负缓存」 | 每张表一个旋钮 | 用户层只留:源文件保留天数、日志保留天数、图片缓存上限;其余进「高级」且默认折叠 | -| 13-settings-automation | 「只读对账:从备份恢复后先开启:只核对库存与路径,不做自动写入。核对完再关闭。」 | 好文案,位置不对 | 文案保留,移入「高级」 | -| 13-settings-sites | 「浏览器服务:原站视图和 Agent 打开站点网页用的 camofox-browser。部署自带的一台由环境变量登记(camofox-env)。」 | 组件名、部署细节 | 「浏览器服务:打开站点网页用。」;实例名显示「内置」 | -| 13-settings-library | 「登记或改路径时会在目录里写哨兵文件 .uhd-root,据此判断库根是否在线」;按钮「检查哨兵」 | 实现机制 | 「保存时会在目录里放一个标记文件,用来判断目录是否挂载。」按钮「检查目录」 | -| 13-settings-library | 命名模板变量表里的「MP 无」标签 | 给开发者的对照 | 删 | -| 13-settings-metadata | 「旧行为。每条资源约 1–2 次搜索 + 命中时 1 次详情(识别缓存命中为 0);每小时 100 条的 RSS 约每天 2400–7200 次请求…」 | 实现细节 + 「旧行为」是开发者口吻 | 「每条新资源都查一次 TMDB。RSS 量大时每天可能上千次请求。」 | -| 13-settings-agent | MCP 区块「Streamable HTTP(POST / GET / DELETE)」「read 16 个 · read + organize.execute 26 个 · admin 35 个」「授权、审计、幂等与控制台一致」 | 接入文档写在设置里 | 设置只留开关、端点、复制配置;其余进 docs 链接 | -| 13-settings-agent | 「fake 脚本(JSON):只对 fake 上游生效」「会话目录:api 与 worker 都要可读写」 | 开发调试项 | 生产构建隐藏 | -| 13-settings-api-keys | scope 名 `organize.read` / `organize.execute` 直接作为选项 | 可接受(给开发者用的页) | 保留英文 scope,前面加中文名「只读 / 读整理记录 / 执行整理 / 管理员」 | -| 全部分区 | 页描述「全局参数、实例与凭证。凭证保存后不回显。」 | 前半句空泛 | 只留「密钥保存后不再显示。」 | - -### 3.14 运行状态 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 14-status | 进程表「9428df7231e2 · pid 29」「io 4 · Agent 0」「SSE 3」 | 容器 ID 与 pid | 这是管理员页,可以保留,但放在「进程」折叠区;默认视图是一行结论「全部正常」 | -| 14-status | 「体积最大的表(前 10)· 含索引与 TOAST」列出 `metadata_field`、`agent_run_event`、`openworkflow.workflow_runs` | 数据库内部表 | 移到「高级 → 数据库」,默认折叠 | -| 14-status | 首页「失败 0」,本页「24 小时失败运行 2」,任务页失败页签「2」 | 三处口径不同 | 首页计划块写「上次失败 0 项」,和本页「24 小时失败」分开表述 | -| 14-status | 「已下线实例 33 个 · 不计入告警,24 小时后清理」 | 容器重建历史 | 删,或只在进程折叠区 | -| 14-status | 图表图例「api · 29api · 29api · 29…」重复拼接 | 渲染问题 | 修图例(bug,单独处理) | - -### 3.15 待处理 / 收件箱 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 15-inbox | 身份类事项只有「原始证据」和「忽略」,没有主操作 | 用户来这里就是要处理,最重要的按钮缺了 | 加「指定作品」主按钮;「原始证据」→「详细信息」 | -| 15-inbox | 每条都挂「警告」「待处理」两个徽章 | 全部一样的徽章等于没有 | 删状态徽章(页面已按状态筛选);级别只标「严重」 | -| 15-inbox | 分组「身份歧义 · 尚未归属作品」「路径冲突 · 系统级」 | 分组名是内部分类 | 「没识别出作品」「媒体库里已有同名文件」 | -| 15-inbox | 路径冲突事项正文 `target_exists` | 错误码 | 「媒体库里已有《星际穿越 (2014)》的同名文件」 | -| 15-inbox | 描述「Agent 调查和重试后仍未解决的事项,按作品和问题类型合并」;事项创建于「刚刚」 | 声称经过调查,实际未必 | 「需要你决定的事」 | -| 15b-inbox-bell | 铃铛下拉写「识别有歧义」,页面写「身份歧义」,首页写「无法确定作品」 | 一物三名 | 统一「没识别出作品」 | - -### 3.16 全局搜索与作品预览 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 17-search | 描述「先看作品和库内状态,需要时再到站点搜资源。」 | 教用户流程 | 删 | -| 17-search | 状态「已建档 · 未入库」「未收录」 | 「建档」「收录」都是内部词,两者区别用户不懂 | 「在媒体库 · 未下载」「不在媒体库」(MP:「已入库 / 缺失」) | -| 17b-command-palette | 底部三条提示「作品卡上可以选站点搜资源」「↑↓ 选择 ↵ 打开」「搜资源在作品详情页」 | 两条说同一件事 | 只留键位提示 | -| 18-tmdb-preview | 按钮「订阅 / 搜索资源 / 建档不订阅」 | 「建档」 | 「订阅 / 搜索资源 / 加入媒体库」 | -| 18-tmdb-preview | 「库内对比:本地账本按 TMDB 身份对应;Emby 查询失败记为未知,不等于缺失」 | 实现声明 | 标题「库中情况」;说明删,Emby 失败时就写「Emby 查询失败」 | - -### 3.17 审计与外壳 - -| 截图 | 现象 | 为什么 | 改成 | -| --- | --- | --- | --- | -| 16-audit | 每行动作列同时显示中文和代码「登录 admin.login_success」,对象列显示 UUID | 双语重复 + ID | 代码与 ID 进行详情;对象显示名称 | -| 16-audit | 「capability.denied」没有中文名 | 翻译漏了 | 「Agent 操作被拒绝」 | -| 全局 | 页面标题 + 描述 + 侧栏说明三层,几乎每页描述都在解释页面 | 模板化 | 列表页默认不写描述;只在需要做决定的页(设置分区)写一句 | -| 全局 | Agent 入口三处:侧栏顶部渐变按钮、右下渐变悬浮按钮、侧栏「Agent 会话」 | 冗余 + 发光渐变 | 保留侧栏项和快捷键;悬浮按钮删或只在窄屏出现 | - -## 4. 设计层面 - -**信息层级**。每页默认视图只回答「现在有没有事要我管」。技术信息分三层:正常视图(名称、状态、结果)→ 详情(路径、时间线、来源)→ 技术信息折叠区(ID、hash、trace、token、模型 ID、错误码)。现在大多数页把第三层放在第一层。 - -**首页该回答的三个问题**: -1. 有没有要我处理的?(待处理数 + 前 3 条,每条带主操作) -2. 最近拿到了什么?(今日入库的作品,海报或列表,MP 的「近期入库」) -3. 有没有东西坏了?(只在出问题时出现:站点登录失效、下载盘快满、服务异常) - -计划带、运行状态、缓存参数、版本目标满足率都不属于这三个问题,移出首页或改为异常时才出现。 - -**徽章、图标、色块**。徽章只用于「不正常」和「需要区分的类别」。正常态(完成、正常、已启用、账号正常、待处理)不加徽章。一行最多一个徽章。卡片内的小卡片(首页媒体概览的三个统计块、待处理页顶部三张计数卡)改成一行文字数字,去掉套娃圆角。 - -**表格 vs 卡片**。同类对象多于 5 个用表格(任务、整理记录、下载、计划);站点这种少量、每个有多项数据的对象用卡片。计划页巡检卡字段太多,应改表格 + 编辑框。 - -**动效信号**。「实时」徽章 + 「更新于 刚刚」+ 刷新按钮 + 自动刷新,四个信号说一件事,留一个「更新于 刚刚」即可。Agent 按钮的彩色渐变描边与发光在侧栏、悬浮按钮、抽屉收起按钮三处重复,品牌色集中在一处用。 - -## 5. 优先级改造清单 - -### 5.1 P0:误导或吓人 - -| # | 改什么 | 文件 | 工作量 | -| --- | --- | --- | --- | -| 1 | 错误码不上屏:整理失败 message 改中文(`identity_unknown`、`blocked:*`),前端统一走一张原因映射表 | `apps/server/src/modules/acquisition-organize/services/organize.ts`、`apps/web/app/lib/labels.ts`、`routes/console/organize*.tsx`、`routes/console/inbox.tsx`、`components/downloads/business-timeline.tsx` | 0.5 天 | -| 2 | 待处理身份类事项加主按钮「指定作品」 | `routes/console/inbox.tsx` | 0.5 天 | -| 3 | 首页「0 个订阅在追踪,自动收录…」改为按数据说话;0 值行隐藏 | `routes/console/home.tsx` | 0.3 天 | -| 4 | 下载行状态反映入库失败,而不是「下载完成」 | `routes/console/downloads.tsx`、`components/downloads/*` | 0.5 天 | -| 5 | 「只读对账」移出首页 | `routes/console/home.tsx`、`components/settings/automation.tsx` | 0.2 天 | -| 6 | 「身份歧义 / 识别有歧义 / 无法确定作品」统一一个说法 | `components/library/labels.ts`、`lib/labels.ts`、服务端 `routes/decisions.ts` | 0.3 天 | - -### 5.2 P1:高频页面的噪音 - -| # | 改什么 | 文件 | 工作量 | -| --- | --- | --- | --- | -| 1 | Agent 会话:三段免责合并为一行「实际结果」;token、模型 ID、工具名进详情;会话标题不用原始提示词 | `components/agent/agent-conversation.tsx`、`routes/console/agent.tsx` | 1 天 | -| 2 | Agent 入口去重与去口号(「交代目标,边做边汇报」删,悬浮按钮删或限窄屏) | `components/console/agent-launcher.tsx`、`components/agent/agent-drawer.tsx`、`routes/console/layout.tsx` | 0.5 天 | -| 3 | 任务列表默认隐藏无业务对象的运行和维护类成功运行;标题不用 ID | `components/tasks/task-stream.tsx`、`routes/console/tasks.tsx` | 0.5 天 | -| 4 | 计划页维护类 18 项合并折叠,说明去表名 | `components/schedules/auto-task-list.tsx`、服务端定时任务描述(`modules/system/retention.ts` 等) | 0.5 天 | -| 5 | 首页重排为三个问题;运行状态、缓存参数、满足率移出或异常才显示 | `routes/console/home.tsx` | 1 天 | -| 6 | 全站删解释型页描述(约 15 处),只保留设置分区的一句话 | `components/console/nav.ts`、各 `routes/console/*.tsx` 的 `PageHeader` | 0.5 天 | -| 7 | 正常态徽章清理:完成、正常、账号正常、接管、待处理 | `home.tsx`、`sites/site-card.tsx`、`downloads.tsx`、`inbox.tsx`、`files.tsx` | 0.5 天 | -| 8 | 术语落地:RSS 统一、媒体库统一、「建档 / 收录」、「资产」「账本」「纳管」「哨兵」「快照」按 §2 改,同步更新 `glossary.md` | 全站 + `docs/design/glossary.md` | 1 天 | -| 9 | 作品详情:UUID、字段来源、别名全集、路径核验折叠 | `routes/console/library.$id.tsx` | 0.5 天 | - -### 5.3 P2:细节 - -| # | 改什么 | 文件 | 工作量 | -| --- | --- | --- | --- | -| 1 | 费用统一两位小数,< 0.01 写「< $0.01」;耗时 < 1 秒写「< 1 秒」 | `lib/format*.ts` | 0.2 天 | -| 2 | 规则页:不支持的关键字不列;「修订」列删;页签改名 | `components/rules/tabs.tsx`、`components/rules/labels.ts` | 0.3 天 | -| 3 | 设置高级项折叠:存储预算、流水保留、缓存有效期、fake 脚本、会话目录、MCP 详情 | `components/settings/*.tsx`、`packages/contracts/src/settings.ts`(字段加 `advanced` 标记) | 0.5 天 | -| 4 | 运行状态页默认只显示结论,表体积、进程、已下线实例折叠;修图例重复 | `routes/console/status.tsx`、`components/status/*` | 0.5 天 | -| 5 | 审计行去掉代码与 UUID,补 `capability.denied` 中文 | `routes/console/audit.tsx` | 0.2 天 | -| 6 | 站点 Passkey 与登录 Passkey 区分命名 | `components/sites/site-accounts-tab.tsx`、`components/settings/account*.tsx` | 0.1 天 | -| 7 | 命令面板提示去重 | 命令面板组件 | 0.1 天 | -| 8 | 清掉用户栈里的测试策略「AGENT-REAL 最小收录策略(测试)」 | 数据,不是代码 | 另开 | - -合计约 P0 2.3 天、P1 6 天、P2 2 天。 - -### 5.4 需要用户拍板 - -1. **「版本目标」是否改名**。候选:「想要的版本」(直白,略长)或沿用 MP 的思路只在升级场景说「洗版」、其余场景说「版本」。改名涉及 139 处字符串和给模型的提示词。 -2. **是否默认隐藏技术信息**。建议:ID、hash、token、模型 ID、错误码、表名一律进「技术信息」折叠区;是否提供全局开关「显示技术细节」(管理员默认关)。 -3. **「Agent 上游」改不改成「模型服务」**。glossary 刚定过「Agent 上游」;用户侧「模型」更好懂,但设置里有 provider / 认证 / 订阅登录,改名要一起理。 -4. **计划页是否只展示用户关心的 11 项**,18 项维护任务收成一行「数据清理」。 -5. **首页是否删掉「运行状态」「计划」两块**,只在异常时出现。 -6. **「收录」「建档」两个词是否全站退场**,换成「加入媒体库 / 在媒体库 / 已下载」。 -7. **Agent 会话里「模型说的(未经核查)」这层防护是否保留**。建议保留一个很轻的标记(回复旁一行「以下是模型的说法」),删掉另外两处。 - -## 6. DEAI-2 处理情况(2026-09-29) - -用户拍板(见 `docs/plan/00-first-version-plan.md`):「版本目标」→「收录版本」;「Agent 上游」→「模型服务」;界面上的 Agent → 「智能体」;技术信息默认折叠(设置 → 界面可默认展开);首页只留三块;计划页维护类收成「数据清理」、智能体巡检置顶;「未经核查」只在最终汇报留一处。术语落地见 [glossary.md](glossary.md)。 - -### P0 - -| # | 状态 | 说明 | -| --- | --- | --- | -| 1 | 完成 | 原因码表 `packages/contracts/src/reasons.ts`,服务端整理记录 message、冲突事项标题/摘要与前端(整理记录、下载时间线、待处理摘要、任务详情)共用;原码进「技术信息」 | -| 2 | 完成 | 「指定作品」主按钮:搜媒体库 + TMDB,走已有 decision resolve(local_entity / manual_tmdb);整理类事项打开重新整理,整理成功后自动关闭事项 | -| 3 | 完成 | 首页状态行按数据说话,0 订阅写「还没有订阅。去搜索添加」 | -| 4 | 部分 | 下载详情在「下载完成但最近一次整理失败」时单独提示入库失败并链到待处理;下载列表行状态未改——需要服务端在下载任务上带最近整理结果,QB-1 正在改整理服务,留给合并后另做 | -| 5 | 完成 | 只读对账移出首页,放进设置 → 自动化 →「高级」 | -| 6 | 完成 | 统一为「没识别出作品」(事项);未确认身份的资源叫「未识别」 | - -### P1 - -| # | 状态 | 说明 | -| --- | --- | --- | -| 1 | 完成 | 见提交说明;对话组件结构不动(另有代理出易用性方案) | -| 2 | 完成 | 删口号;悬浮按钮只在无侧栏的窄屏出现,抽屉打开时不再显示胶囊 | -| 3 | 完成 | 默认隐藏系统任务(可一键显示),标题不用 ID | -| 4 | 完成 | 维护类合成「数据清理」组;自动任务按分类折叠并记忆;说明去表名 | -| 5 | 完成 | | -| 6 | 完成 | 约 14 处页描述删除或改一句 | -| 7 | 完成 | 首页、站点卡、下载、待处理、文件管理、整理记录 | -| 8 | 完成 | RSS、媒体库、建档 / 收录、资产、账本、纳管、哨兵、快照;「外部身份」一词在作品详情改「匹配的 TMDB 条目」,其余处保留 | -| 9 | 完成 | UUID、字段来源、别名全集、路径核验 | - -### P2 - -| # | 状态 | 说明 | -| --- | --- | --- | -| 1 | 完成 | `formatUsd`、`formatDuration` | -| 2 | 完成 | | -| 3 | 部分 | 自动化分区的只读对账 / 存储预算 / 流水保留 / 缓存有效期收进「高级」;会话目录与 fake 脚本只在开发构建显示;没有在 contracts 加 `advanced` 标记(纯前端即可) | -| 4 | 完成 | 进程、趋势、最大表折叠;图例同名序列加序号 | -| 5 | 完成 | | -| 6 | 完成 | | -| 7 | 完成 | | -| 8 | 不做 | 用户栈数据,不是代码 | - -### 页面级条目中不做的 - -- 05b 站点概况的配置回显、05c 资源行「已识别,无收录版本」、「实时补查」按钮位置:DETAIL-1 / SEARCH-3 正在改站点详情与资源列表,只改了名词(抓取、去站点搜),结构留给它们。 -- 10 整理记录里连续的 0 文件失败行合并:需要服务端按下载任务聚合,放到 QB-1 合并之后。 -- 12 媒体库页签只留「作品 / 未识别」、「未命中订阅」不进未识别:DH-1 正在改身份服务,避免冲突。 -- 13-settings-agent MCP 区块的能力计数与接入说明移到文档:保留,只改了一句说明。 -- 14 「已下线实例 N 个」文案:已随进程区折叠,文案不改。 diff --git a/docs/design/file-preview-research.md b/docs/design/file-preview-research.md deleted file mode 100644 index 4cf5ec83..00000000 --- a/docs/design/file-preview-research.md +++ /dev/null @@ -1,37 +0,0 @@ -# 文件管理基础预览调研(FM-2) - -2026-09-29。范围:文件管理详情抽屉里除视频播放以外的预览。前提:单容器 4C/8G;前端库只能来自 npm;所有读取走 `resolveIn` + `recheck`(realpath 在登记目录内、符号链接目标也须在内),仅管理员控制台会话。 - -**核实**:镜像 `/usr/local/bin` 只有 `ffprobe` 9.0.2(141 MB,取自 `mwader/static-ffmpeg:9.0.2`),**没有 ffmpeg**。同一镜像里的 ffmpeg 静态二进制也是 141 MB,加进来要改 Dockerfile 和编译参数 `--allow-run`。 - -**MP 对照**:MoviePilot 文件管理只有图片预览(`/storage/image` 取原图转 blob),另有识别和刮削,没有文本、字幕和种子预览。 - -## 逐项结论 - -| 类别 | 用户价值 | 实现 | 安全 | 工作量 | 建议 | -| --- | --- | --- | --- | --- | --- | -| 图片 jpg/png/webp/avif/gif | 高:核对海报、背景是否刮对 | 原图经 `/files/download?inline` 显示(≤20 MB,`loading=lazy`);服务端读文件头回宽高 | SVG 不内联(可带脚本);`nosniff` + `sandbox` CSP | S | **已做** | -| 图片缩略图 | 中:列表网格、海报墙 | 需 ffmpeg(+141 MB)或 sharp/libvips(npm 原生模块,`deno compile` 嵌入风险)或 wasm 解码(内存峰值高) | 解码炸弹(超大分辨率):限像素数 | M | 后做,等有网格视图再定 | -| 文本 nfo/txt/log/md/json/xml/yaml | 高:看 NFO、发布说明、日志 | 服务端读前 1 MB,编码探测 BOM → UTF-16 → UTF-8 → GB18030/Big5 择优 → Latin-1;json 美化 | 一律按纯文本渲染(React 转义),md 不渲染 HTML | S | **已做** | -| Markdown 渲染 | 低 | markdown-it + DOMPurify(约 60 KB) | 必须消毒 | S | 不做,纯文本够用 | -| 字幕 srt/vtt/ass/ssa | 高:确认语言、编码、时间轴对不对 | 服务端解析前 1 MB,按时间排序回前 200 条;ASS 取 `Title`、去覆写标签 | 纯文本输出 | S | **已做** | -| 字幕 sup(PGS) | 中 | 解析段头,只列起止时间 | 只读段头 | S | **已做**;渲染图形不做 | -| 音频 flac/mp3 试听 | 低:库里音频多是音轨附件 | 浏览器 `