Imported from lawrenceching/SMM (
AGENTS.md). Install upstream withnpx skills add lawrenceching/SMM. Copyright stays with the author.
SMM
本项目为多媒体管理桌面应用. 项目基于 monorepo 管理, 使用 pnpm 作为包管理器.
项目结构
Packages (共享包)
| 包名 | 描述 |
|---|---|
| packages/types | 跨端共享类型、interface、Zod schema |
| packages/utils | 无业务语义纯工具(Path、locale、uri/url 等) |
| packages/test | 测试工具包, 提供测试相关的工具函数 |
| packages/core-routes | 实现通用 HTTP 接口, apps/cli, apps/electron, apps/ohos 都会复用这些接口 |
Apps (应用)
| 应用 | 描述 |
|---|---|
| apps/ui | 前端应用, 基于 React 19 + Tailwind CSS 4 + Shadcn UI + Vite 7 |
| apps/core | 业务 Core(@smm/core),headless 业务逻辑与 Ports 抽象 |
| apps/cli | 后端服务, 基于 Bun + Hono + Socket.IO |
| apps/electron | Electron 桌面应用, 将 ui 和 cli 打包成桌面应用 |
| apps/e2e | 端到端测试, 基于 WebdriverIO |
| apps/docker | Docker 镜像构建配置 |
| apps/ohos | 鸿蒙 HarmonyOS 应用 |
核心模块详解
packages/types
- 共享 DTO、事件类型、AI tool schema、Job 类型等(
@smm/types)
packages/utils
path.ts- 路径处理(@smm/utils/path)uri.ts/url.ts- URI/URL 工具locale.ts/proxiableFetch.ts/errors.ts等无业务语义工具
apps/core(@smm/core)
- 业务 Core:媒体元数据、用户配置、AI tool 实现、rename 校验、whitelistedCmd 等
- Ports 定义(FsPort、NetworkPort、LoggingPort 等)与 use-case 编排
apps/ui
前端应用, 主要目录结构:
src/api/- API 调用层src/components/- UI 组件dialogs/- 对话框组件sidebar/- 侧边栏组件ui/- Shadcn UI 组件background-jobs/- 后台任务组件mcp/- MCP 相关组件
src/ai/- AI 助手相关代码src/actions/- 状态操作public/locales/- 多语言文件 (en, zh-CN, zh-HK, zh-TW)
技术栈:
- React 19
- Tailwind CSS 4
- Shadcn UI (Radix UI)
- Vite 7
- Zustand (状态管理)
- TanStack Query
- Socket.IO Client
- AI SDK (@ai-sdk/react, @assistant-ui/react)
Shadcn UI 的 cli 对 monorepo 的支持不友好, 无法通过 cli 安装组件.
请手动安装组件, 并在 apps/ui/src/components/ui/ 目录下创建对应的组件文件.
apps/cli
后端服务, 主要目录结构:
src/route/- HTTP API 路由ffmpeg/- FFmpeg 相关 API (转换、截图)mediaMetadata/- 媒体元数据 APIytdlp/- yt-dlp 相关 API (下载、提取数据)
src/tools/- 业务工具函数src/mcp/- MCP (Model Context Protocol) 服务器tools/- MCP 工具定义
src/utils/- 工具函数src/validations/- 验证逻辑src/events/- Socket.IO 事件处理src/i18n/- 国际化配置
技术栈:
- Bun (运行时)
- Hono (Web 框架)
- Socket.IO (实时通信)
- MCP SDK (@modelcontextprotocol/sdk)
- AI SDK (@ai-sdk/openai)
- Pino (日志)
apps/electron
Electron 桌面应用, 主要目录结构:
src/main/- 主进程代码src/preload/- 预加载脚本src/renderer/- 渲染进程入口build/- 构建资源 (图标等)
技术栈:
- Electron 39
- electron-vite
- electron-builder
apps/convex
基于 Convex 的后台 API 服务
apps/e2e
端到端测试, 主要目录结构:
test/specs/- 测试用例test/pageobjects/- 页面对象test/componentobjects/- 组件对象test/lib/- 测试工具
技术栈:
- WebdriverIO 9
- Mocha
代码改动
Post Change run build and typecheck script after code change Pre Commit run build, typecheck, and unit tests before commit
常用命令
# 开发
pnpm dev # 同时启动 ui 和 cli 开发服务器
pnpm dev:ui # 启动 ui 开发服务器
pnpm dev:cli # 启动 cli 开发服务器
pnpm dev:electron # 启动 Electron 开发模式
# 构建
pnpm build # 构建 cli 和 ui
pnpm build:electron # 构建 Electron 应用
# 测试
pnpm test # 运行所有测试
pnpm test:core # 运行 core 测试
pnpm test:cli # 运行 cli 测试
pnpm test:ui # 运行 ui 测试
pnpm test:e2e # 运行 e2e 测试
# 类型检查
pnpm typecheck # 运行所有类型检查
# CI
pnpm ci # 构建 + 测试 + 类型检查
发版
维护者发布 Electron 桌面版 与 Docker 镜像 的流程见 docs/dev/release.md(共用 Git tag、单 GitHub Release 多产物、Docker 发版前 E2E gate 校验)。
核心术语
媒体文件夹(Media Folder) 保存了电视剧, 动画, 电影或音乐的本地文件夹
媒体库(Media Library) 保存了多个媒体文件夹的文件夹
识别多媒体文件夹(Recognize Media Folder): 该操作用于指定文件夹保存的是哪一部电视剧或电影的视频文件
识别季集视频文件(Recognize Episode Video File): 该操作用于指定电视剧每一集对应的本地视频文件
元数据(Media Metadata): 元数据, 保存了文件夹对应的电视剧或电影的信息,以及本地视频文件和季集的对应关系
视频文件和关联文件(Video File and Associated Files) 视频文件通常还对应着字幕文件, 音频文件, 封面文件和 NFO 文件等, 这类文件被称为关联文件
DVD UI组件 Download Video Dialog, 其代码位于 apps/ui/src/components/dialogs/UIDownloadVideoDialogContent.tsx
技术架构
见 架构总览
前后端通信
- HTTP API: 使用 Hono 框架提供 RESTful API
- Socket.IO: 使用 Socket.IO 进行实时双向通信
- MCP: 提供 Model Context Protocol 服务器, 支持 AI 工具调用
AI 集成
- 前端使用
@assistant-ui/react提供 AI 对话界面 - 后端使用
@ai-sdk/openai集成 OpenAI API - MCP 服务器提供工具调用能力
媒体处理
- FFmpeg: 视频转换、截图
- yt-dlp: 视频下载
- TMDB: 媒体信息搜索和获取
- NFO: 媒体元数据文件读写
国际化
- 前端使用
i18next+react-i18next - 后端使用
i18next+i18next-fs-backend - 支持语言: English, 简体中文, 繁体中文(香港), 繁体中文(台湾)
代码架构
apps/ui
apps/ui/src/hooks/userConfig/ 该目录提供了基于 TanStack Query 的读取和写入应用配置的方法, 如 useConfig.ts
pps/ui/src/stores/uiMediaFolderStore.ts 基于 Zustand 的全局状态类. 接口 UIMediaFolder 用于表示前端的多媒体目录. 该store是前端项目的核心状态, 被Sidebar, Statusbar, TvShowPanel, MoviePanle 和 MoviePanel 等主要组件依赖.
apps/ui/src/hooks/mediaMetadata/ 基于 TanStack Query 的 MediaMetadata 读取和写入方法
端到端测试
apps/e2e 是端到端测试目录
其使用 webdriver.io 运行基于浏览器的端到端测试
代码结构
本项目主要代码在 apps/e2e/test 目录下
- actions - 可复用的测试动作
- componentobjects - Component Object (简称CO), 用于表示应用界面的一个组件, 辅助开发者操作该组件的各个元素
- pageobject - 用于操作网页
- lib - 可复用的辅助函数
- specs - 端到端测试用例
执行测试
自动化测试/AI Agent测试 在项目根目录执行
bun ci/run-e2e-test.ts --spec ./test/specs/[test file].e2e.ts
日志由 apps/cicd 写入 artifacts/cicd/<commandId>/,每个 spec 文件对应一个 task(如 SearchMovie.e2e.ts/main.log)。
浏览器网络请求日志在 artifacts/cicd/[commandId]/[testFileName]/network-log 目录.
网络请求日志通常非常庞大, 不适宜直接文件
请使用 query-network-log 工具查询
编写测试
关键辅助测试函数
apps\e2e\test\lib\testbed.ts创建和清理测试环境apps\e2e\test\actions\import-folders.ts创建和导入测试媒体目录
模板
- 测试音乐和视频目录:
apps\e2e\common\music\MusicPanel.template.ts
apps/cli API 列表
API列表可查阅文件: docs/api/index.md.
注意事项
- 当代码改动涉及
apps/ohos时, 需要阅读 HarmonyOS 开发 FAQ
Superpowers Skill
当使用 superpowers skillset 驱动改动时, 在 "writing-plans" 阶段, 需要为本项目额外编写/更新一份设计文档.
文档模板: Design Template