{"owner":"imsyy","repo":"SPlayer","hasSkills":true,"totalSkillsCount":4,"totalTokensCount":4776,"categories":["anthropic-skill","claude-rule","root-instruction","project-spec"],"hasMcp":false,"mcpConfig":null,"found":["native/tools/package.json","CLAUDE.md","AGENTS.md","docs/api.md"],"skills":{"native/tools/package.json":"{\n  \"name\": \"tools\",\n  \"version\": \"0.1.0\",\n  \"main\": \"tools.node\",\n  \"types\": \"index.d.ts\",\n  \"napi\": {\n    \"binaryName\": \"tools\"\n  },\n  \"scripts\": {\n    \"build\": \"napi build --release --no-const-enum\",\n    \"build:debug\": \"napi build --no-const-enum\"\n  },\n  \"devDependencies\": {\n    \"@napi-rs/cli\": \"^3\"\n  }\n}\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nSPlayer is a desktop music player built with **Electron + Vue 3 + TypeScript**. It uses Naive UI for components, Pinia for state management, and integrates with NetEase Cloud Music API, Last.fm, and Subsonic/Navidrome streaming services. Native Rust modules provide OS-level features (taskbar lyrics on Windows, MPRIS on Linux, SMTC on Windows, Discord RPC).\n\n## Commands\n\n```bash\npnpm dev                # Start dev environment (builds native modules + launches Electron)\npnpm build              # Full production build (typecheck + electron-vite build)\npnpm build:win          # Package for Windows\npnpm build:mac          # Package for macOS\npnpm build:linux        # Package for Linux\npnpm lint               # ESLint (--max-warnings=0, zero tolerance)\npnpm format             # Prettier\npnpm typecheck          # Full TypeScript check (node + web)\npnpm typecheck:node     # Main process + preload TypeScript check\npnpm typecheck:web      # Renderer process TypeScript check\n```\n\nSet `SKIP_NATIVE_BUILD=true` to skip Rust native module compilation during dev.\n\n## Architecture\n\n### Process Model (Electron)\n\n- **Main process** (`electron/main/`): Window management, IPC handlers, SQLite database, system tray, global shortcuts, Fastify API server, native module integration\n- **Preload** (`electron/preload/`): Context bridge exposing `window.api.store` and `window.logger` to renderer\n- **Renderer** (`src/`): Vue 3 SPA — the UI\n\n### IPC Layer\n\n18 IPC modules in `electron/main/ipc/` handle all main↔renderer communication: `ipc-cache`, `ipc-file`, `ipc-lyric`, `ipc-media`, `ipc-mpv`, `ipc-socket`, `ipc-store`, `ipc-taskbar`, `ipc-tray`, `ipc-window`, `ipc-system`, `ipc-shortcut`, `ipc-update`, `ipc-protocol`, `ipc-mac-statusbar`, `ipc-thumbar`, `ipc-renderer-log`.\n\n### Renderer Architecture (`src/`)\n\n- **Stores** (`stores/`): Pinia with persistedstate — `data` (songs/user), `status` (playback), `setting` (config), `local` (local music), `music`, `streaming`, `shortcut`\n- **Core** (`core/`): `audio-player/` (playback engine), `automix/`, `player/` (state), `resource/` (caching)\n- **API** (`api/`): Axios-based, organized by domain (song, playlist, login, streaming, lastfm)\n- **Composables** (`composables/`): `useInit`, `useSongMenu`, `useQualityControl`, etc.\n- **Components** (`components/`): AMLL (lyrics), Card, Common, Global, Layout, List, Menu, Modal, Player, Search, Setting, UI\n\n### Native Modules (`native/`)\n\nRust-based, built via `scripts/build-native.ts`:\n\n- `taskbar-lyric` — Windows taskbar lyrics display\n- `external-media-integration` — OS media integration\n- `smtc-for-splayer` — Windows System Media Transport Controls\n- `mpris-for-splayer` — Linux MPRIS support\n- `discord-rpc-for-splayer` — Discord Rich Presence\n- `ferrous-opencc-wasm` — Chinese character conversion (WASM)\n\n### Embedded Server\n\n`electron/server/` runs a Fastify instance (port 25884 default) wrapping NetEase Cloud Music API, proxied via `/api` in dev.\n\n## Path Aliases\n\n```\n@/       → src/\n@emi/    → native/external-media-integration\n@shared/ → src/types/shared\n@opencc/ → native/ferrous-opencc-wasm/pkg\n@native/ → native/\n```\n\n## Code Conventions\n\n- **Language**: Comments and commit messages in Chinese\n- **Vue**: Composition API with `<script setup>`, TypeScript throughout\n- **Auto-imports**: Vue, vue-router, @vueuse/core, and naive-ui composables are auto-imported (no explicit imports needed)\n- **Naive UI components**: Auto-resolved via `unplugin-vue-components`\n- **Unused variables**: Prefix with `_` to suppress lint warnings\n- **Prettier**: Double quotes, trailing commas, 2-space indent, 100 char width\n- **Workers**: Heavy computation (audio analysis) runs in worker threads (`electron/main/workers/`)\n- **TypeScript**: Composite project — `tsconfig.node.json` (main/preload/scripts) and `tsconfig.web.json` (renderer)\n","AGENTS.md":"# AI 开发助手行为准则\n\n## 项目技术栈与环境\n\n- **核心框架**: Vue 3 + Electron\n- **UI 组件库**: **Naive UI** (严禁混用其他 UI 库)\n- **包管理器**: **严格使用 `pnpm`** (严禁使用 npm/yarn)\n- **开发命令**: `pnpm dev` (预览代码)\n- **代码质量**: 每次任务结束前，必须自动运行 `pnpm lint` 并修复所有问题，确保 0 错误、0 警告后方可交付。\n- **提交之前**: 必须运行 `pnpm build` 和 `pnpm format` 并修复所有问题，确保 0 错误、0 警告后方可提交。\n\n## 代码风格与规范\n\n### 1. 注释规范\n\n- **语言**: 必须使用**中文**。\n- **格式**: 保持简洁，禁止长句、英文长文或带序号的注释。\n  - 正确: `// 监听主进程消息`\n  - 错误: `// 1. listen to main process`, `// this function handles ipc...`\n\n### 2. UI 组件使用 Naive UI\n\n- **原则**: 严禁重复造轮子。所有通用交互必须优先使用 Naive UI 组件。\n- **处理方式**: 如果未找到合适组件，必须先询问用户，禁止擅自手写原生 CSS/HTML 组件。\n  - 正确: 使用 `<n-button type=\"primary\">`, `<n-modal>`, `<n-message-provider>`\n  - 错误: 手写 `<div class=\"my-btn\">` 或引入 Element Plus 等其他库。\n\n### 3. 图标\n\n- **原则**: 优先复用项目 `src/assets/icons` 或现有图标方案。\n- **具体实现**: 严格遵循项目现有的图标组件用法。\n  - 正确: `<SvgIcon :name=\"isLikeAlbum ? 'Favorite' : 'FavoriteBorder'\" />`\n  - 错误: 擅自引入 `xicons` (除非用户明确允许) 或手写 SVG 代码。\n\n### 4. Electron 特性规范\n\n- **进程安全**: 明确代码运行环境（Main vs Renderer）。不要在渲染进程中直接调用不安全的 Node.js API，应优先使用 IPC 通信或 Preload 脚本暴露的 API。\n- **通信规范**: 涉及 IPC 通信时，保持频道命名清晰且常量化。\n\n### 5. 测试与清理\n\n- **临时文件**: 任务过程中生成的临时测试文件（如 `test_lrc.ts`），必须在任务结束前自动删除，严禁推送到代码库。\n\n## 交互与思维链\n\n### 1. 遇到困难多确认\n\n- **原则**: 禁止假设。当遇到不理解的概念（特别是 Electron 的通信逻辑或原生能力调用）时，**必须**暂停并向用户提问。\n  - 禁止: “我猜用户是想在渲染进程直接读文件...” -> 导致安全报错。\n  - 建议: “此处涉及文件系统操作，请确认是通过 IPC 调用主进程处理，还是使用现有的工具函数？”\n\n### 2. 复杂任务先规划\n\n- **文档驱动开发**: 遇到复杂功能（如窗口管理、系统托盘、复杂逻辑重构）时，**必须**先创建一个临时的 Markdown 文档（如 `name_of_task.md`）。\n- **流程**: 在文档中梳理思路 -> 展示给用户 -> 用户同意 -> 开始写代码。\n\n### 3. 复用优先DRY原则\n\n- **原则**: 在编写新功能前，强制检索项目现存代码。\n- **自检**: “项目中是否已经有类似的 IPC 封装或 UI 组件？”如果是，直接复用。\n\n### 4. 聊天方式\n\n- **原则**: 与用户保持中文对话，禁止使用英文或其他语言。\n- **具体实现**: 所有与用户的交互（包括问题、指令、代码展示等）都必须用中文进行。\n\n## 严格合规声明\n\n- **指令等级**: Critical。\n- **违规后果**: 违反以上任何一条规则将被定义为**任务失败**，代码将被直接拒绝。请务必严格执行上述标准。\n","docs/api.md":"# API 接口文档\n\n## 概述\n\n本软件提供了本地 HTTP API 服务，用于控制播放器和访问音乐服务。默认端口为 `25884`\n\n## 基础信息\n\n- **基础 URL**: `http://localhost:25884`\n- **API 前缀**: `/api`\n- **响应格式**: JSON\n\n## 统一响应格式\n\n所有接口都遵循以下响应格式：\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"操作成功\",\n  \"data\": {}\n}\n```\n\n### 状态码说明\n\n- `200`: 成功\n- `500`: 服务器错误\n\n---\n\n## 播放控制接口 (Control API)\n\n**基础路径**: `/api/control`\n\n### 播放\n\n**接口**: `GET /api/control/play`\n\n**描述**: 发送播放命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 暂停\n\n**接口**: `GET /api/control/pause`\n\n**描述**: 发送暂停命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"暂停命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 播放/暂停切换\n\n**接口**: `GET /api/control/toggle`\n\n**描述**: 切换播放/暂停状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放/暂停切换命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 下一曲\n\n**接口**: `GET /api/control/next`\n\n**描述**: 播放下一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"下一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 上一曲\n\n**接口**: `GET /api/control/prev`\n\n**描述**: 播放上一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"上一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 获取状态\n\n**接口**: `GET /api/control/status`\n\n**描述**: 获取软件版本、环境数据和连接状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取状态成功\",\n  \"data\": {\n    \"version\": {\n      \"app\": \"3.0.0-beta.6\",\n      \"name\": \"SPlayer\"\n    },\n    \"environment\": {\n      \"platform\": \"win32\",\n      \"arch\": \"x64\",\n      \"nodeVersion\": \"20.x.x\",\n      \"electronVersion\": \"x.x.x\",\n      \"chromeVersion\": \"x.x.x\",\n      \"v8Version\": \"x.x.x\"\n    },\n    \"connected\": true,\n    \"window\": \"available\"\n  }\n}\n```\n\n**响应字段说明**:\n\n- `version.app`: 软件版本号\n- `version.name`: 软件名称\n- `environment.platform`: 操作系统平台 (win32/darwin/linux)\n- `environment.arch`: 系统架构 (x64/arm64)\n- `environment.nodeVersion`: Node.js 版本\n- `environment.electronVersion`: Electron 版本\n- `environment.chromeVersion`: Chrome 版本\n- `environment.v8Version`: V8 引擎版本\n- `connected`: 是否已连接\n- `window`: 窗口状态\n\n---\n\n### 获取当前播放信息\n\n**接口**: `GET /api/control/song-info`\n\n**描述**: 获取当前播放的歌曲信息\n\n> [!WARNING]\n> 请勿频繁调用此接口（如每秒调用一次）来获取播放进度，这会导致软件性能异常。\n> 如需实时获取播放进度和状态，请使用 WebSocket 连接并监听相关事件。\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取当前播放信息成功\",\n  \"data\": {\n    \"playStatus\": \"play\",\n    \"playName\": \"歌曲名\",\n    \"artistName\": \"歌手名\",\n    \"albumName\": \"专辑名\",\n    \"currentTime\": 123.45,\n    \"volume\": 1,\n    \"playRate\": 1,\n    \"id\": 123456,\n    \"name\": \"歌曲名\",\n    \"artists\": \"歌手名\",\n    \"album\": \"专辑名\",\n    \"cover\": \"http://...\",\n    \"duration\": 300,\n    \"lrcData\": [],\n    \"yrcData\": []\n  }\n}\n```\n\n---\n\n## 云音乐 API (Netease API)\n\n**基础路径**: `/api/netease`\n\n### 使用说明\n\n云音乐 API 支持所有 NeteaseCloudMusicApi Enhanced 的接口。接口路径会自动转换为 kebab-case 格式。\n\n**示例**:\n\n- `GET /api/netease/login/cellphone?phone=xxx&password=xxx`\n- `GET /api/netease/user/playlist?uid=xxx`\n- `GET /api/netease/song/detail?ids=xxx`\n\n更多接口请参考 [NeteaseCloudMusicApi Enhanced 文档](https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced)\n\n---\n\n## 解锁 API (Unblock API)\n\n**基础路径**: `/api/unblock`\n\n### 云音乐解锁\n\n**接口**: `GET /api/unblock/netease?id={songId}`\n\n**描述**: 获取网易云音乐解锁后的播放链接\n\n**请求参数**:\n\n- `id` (必需): 歌曲 ID\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 酷我解锁\n\n**接口**: `GET /api/unblock/kuwo?keyword={keyword}`\n\n**描述**: 获取酷我音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 波点解锁\n\n**接口**: `GET /api/unblock/bodian?keyword={keyword}`\n\n**描述**: 获取波点音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n## 全部 API 列表\n\n**接口**: `GET /api`\n\n**描述**: 获取所有 API 模块列表\n\n**响应示例**:\n\n```json\n{\n  \"name\": \"SPlayer API\",\n  \"description\": \"SPlayer API service\",\n  \"author\": \"@imsyy\",\n  \"list\": [\n    {\n      \"name\": \"NeteaseCloudMusicApi\",\n      \"url\": \"/api/netease\"\n    },\n    {\n      \"name\": \"UnblockAPI\",\n      \"url\": \"/api/unblock\"\n    }\n  ]\n}\n```\n\n---\n\n## 错误处理\n\n当接口发生错误时，会返回以下格式：\n\n```json\n{\n  \"code\": 500,\n  \"message\": \"错误描述\",\n  \"data\": null\n}\n```\n\n常见错误：\n\n- `主窗口未找到`: 应用程序主窗口未初始化\n- `播放失败`: 播放操作执行失败\n- `获取状态失败`: 状态获取失败\n\n---\n\n### 使用示例\n\n#### cURL 示例\n\n```bash\n# 播放\ncurl http://localhost:25884/api/control/play\n\n# 暂停\ncurl http://localhost:25884/api/control/pause\n\n# 下一曲\ncurl http://localhost:25884/api/control/next\n\n# 获取状态\ncurl http://localhost:25884/api/control/status\n```\n\n#### JavaScript 示例\n\n```javascript\n// 播放\nfetch(\"http://localhost:25884/api/control/play\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n\n// 获取状态\nfetch(\"http://localhost:25884/api/control/status\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n```\n\n#### Python 示例\n\n```python\nimport requests\n\n# 播放\nresponse = requests.get('http://localhost:25884/api/control/play')\nprint(response.json())\n\n# 获取状态\nresponse = requests.get('http://localhost:25884/api/control/status')\nprint(response.json())\n```\n\n---\n\n## 注意事项\n\n1. 所有接口仅在应用程序运行时可用\n2. HTTP API 默认端口为 `25884`，可在环境变量 `VITE_SERVER_PORT` 中配置\n3. WebSocket API 默认端口为 `25885`，可在应用程序设置中修改\n4. 解锁接口仅供学习使用，请勿用于商业用途\n5. 网易云音乐 API 需要登录后才能使用部分功能\n6. 接口响应时间取决于网络状况和服务器负载\n7. WebSocket 连接支持心跳检测（PING/PONG），建议客户端定期发送心跳以保持连接\n\n---\n"},"files":{"native/tools/package.json":"{\n  \"name\": \"tools\",\n  \"version\": \"0.1.0\",\n  \"main\": \"tools.node\",\n  \"types\": \"index.d.ts\",\n  \"napi\": {\n    \"binaryName\": \"tools\"\n  },\n  \"scripts\": {\n    \"build\": \"napi build --release --no-const-enum\",\n    \"build:debug\": \"napi build --no-const-enum\"\n  },\n  \"devDependencies\": {\n    \"@napi-rs/cli\": \"^3\"\n  }\n}\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nSPlayer is a desktop music player built with **Electron + Vue 3 + TypeScript**. It uses Naive UI for components, Pinia for state management, and integrates with NetEase Cloud Music API, Last.fm, and Subsonic/Navidrome streaming services. Native Rust modules provide OS-level features (taskbar lyrics on Windows, MPRIS on Linux, SMTC on Windows, Discord RPC).\n\n## Commands\n\n```bash\npnpm dev                # Start dev environment (builds native modules + launches Electron)\npnpm build              # Full production build (typecheck + electron-vite build)\npnpm build:win          # Package for Windows\npnpm build:mac          # Package for macOS\npnpm build:linux        # Package for Linux\npnpm lint               # ESLint (--max-warnings=0, zero tolerance)\npnpm format             # Prettier\npnpm typecheck          # Full TypeScript check (node + web)\npnpm typecheck:node     # Main process + preload TypeScript check\npnpm typecheck:web      # Renderer process TypeScript check\n```\n\nSet `SKIP_NATIVE_BUILD=true` to skip Rust native module compilation during dev.\n\n## Architecture\n\n### Process Model (Electron)\n\n- **Main process** (`electron/main/`): Window management, IPC handlers, SQLite database, system tray, global shortcuts, Fastify API server, native module integration\n- **Preload** (`electron/preload/`): Context bridge exposing `window.api.store` and `window.logger` to renderer\n- **Renderer** (`src/`): Vue 3 SPA — the UI\n\n### IPC Layer\n\n18 IPC modules in `electron/main/ipc/` handle all main↔renderer communication: `ipc-cache`, `ipc-file`, `ipc-lyric`, `ipc-media`, `ipc-mpv`, `ipc-socket`, `ipc-store`, `ipc-taskbar`, `ipc-tray`, `ipc-window`, `ipc-system`, `ipc-shortcut`, `ipc-update`, `ipc-protocol`, `ipc-mac-statusbar`, `ipc-thumbar`, `ipc-renderer-log`.\n\n### Renderer Architecture (`src/`)\n\n- **Stores** (`stores/`): Pinia with persistedstate — `data` (songs/user), `status` (playback), `setting` (config), `local` (local music), `music`, `streaming`, `shortcut`\n- **Core** (`core/`): `audio-player/` (playback engine), `automix/`, `player/` (state), `resource/` (caching)\n- **API** (`api/`): Axios-based, organized by domain (song, playlist, login, streaming, lastfm)\n- **Composables** (`composables/`): `useInit`, `useSongMenu`, `useQualityControl`, etc.\n- **Components** (`components/`): AMLL (lyrics), Card, Common, Global, Layout, List, Menu, Modal, Player, Search, Setting, UI\n\n### Native Modules (`native/`)\n\nRust-based, built via `scripts/build-native.ts`:\n\n- `taskbar-lyric` — Windows taskbar lyrics display\n- `external-media-integration` — OS media integration\n- `smtc-for-splayer` — Windows System Media Transport Controls\n- `mpris-for-splayer` — Linux MPRIS support\n- `discord-rpc-for-splayer` — Discord Rich Presence\n- `ferrous-opencc-wasm` — Chinese character conversion (WASM)\n\n### Embedded Server\n\n`electron/server/` runs a Fastify instance (port 25884 default) wrapping NetEase Cloud Music API, proxied via `/api` in dev.\n\n## Path Aliases\n\n```\n@/       → src/\n@emi/    → native/external-media-integration\n@shared/ → src/types/shared\n@opencc/ → native/ferrous-opencc-wasm/pkg\n@native/ → native/\n```\n\n## Code Conventions\n\n- **Language**: Comments and commit messages in Chinese\n- **Vue**: Composition API with `<script setup>`, TypeScript throughout\n- **Auto-imports**: Vue, vue-router, @vueuse/core, and naive-ui composables are auto-imported (no explicit imports needed)\n- **Naive UI components**: Auto-resolved via `unplugin-vue-components`\n- **Unused variables**: Prefix with `_` to suppress lint warnings\n- **Prettier**: Double quotes, trailing commas, 2-space indent, 100 char width\n- **Workers**: Heavy computation (audio analysis) runs in worker threads (`electron/main/workers/`)\n- **TypeScript**: Composite project — `tsconfig.node.json` (main/preload/scripts) and `tsconfig.web.json` (renderer)\n","AGENTS.md":"# AI 开发助手行为准则\n\n## 项目技术栈与环境\n\n- **核心框架**: Vue 3 + Electron\n- **UI 组件库**: **Naive UI** (严禁混用其他 UI 库)\n- **包管理器**: **严格使用 `pnpm`** (严禁使用 npm/yarn)\n- **开发命令**: `pnpm dev` (预览代码)\n- **代码质量**: 每次任务结束前，必须自动运行 `pnpm lint` 并修复所有问题，确保 0 错误、0 警告后方可交付。\n- **提交之前**: 必须运行 `pnpm build` 和 `pnpm format` 并修复所有问题，确保 0 错误、0 警告后方可提交。\n\n## 代码风格与规范\n\n### 1. 注释规范\n\n- **语言**: 必须使用**中文**。\n- **格式**: 保持简洁，禁止长句、英文长文或带序号的注释。\n  - 正确: `// 监听主进程消息`\n  - 错误: `// 1. listen to main process`, `// this function handles ipc...`\n\n### 2. UI 组件使用 Naive UI\n\n- **原则**: 严禁重复造轮子。所有通用交互必须优先使用 Naive UI 组件。\n- **处理方式**: 如果未找到合适组件，必须先询问用户，禁止擅自手写原生 CSS/HTML 组件。\n  - 正确: 使用 `<n-button type=\"primary\">`, `<n-modal>`, `<n-message-provider>`\n  - 错误: 手写 `<div class=\"my-btn\">` 或引入 Element Plus 等其他库。\n\n### 3. 图标\n\n- **原则**: 优先复用项目 `src/assets/icons` 或现有图标方案。\n- **具体实现**: 严格遵循项目现有的图标组件用法。\n  - 正确: `<SvgIcon :name=\"isLikeAlbum ? 'Favorite' : 'FavoriteBorder'\" />`\n  - 错误: 擅自引入 `xicons` (除非用户明确允许) 或手写 SVG 代码。\n\n### 4. Electron 特性规范\n\n- **进程安全**: 明确代码运行环境（Main vs Renderer）。不要在渲染进程中直接调用不安全的 Node.js API，应优先使用 IPC 通信或 Preload 脚本暴露的 API。\n- **通信规范**: 涉及 IPC 通信时，保持频道命名清晰且常量化。\n\n### 5. 测试与清理\n\n- **临时文件**: 任务过程中生成的临时测试文件（如 `test_lrc.ts`），必须在任务结束前自动删除，严禁推送到代码库。\n\n## 交互与思维链\n\n### 1. 遇到困难多确认\n\n- **原则**: 禁止假设。当遇到不理解的概念（特别是 Electron 的通信逻辑或原生能力调用）时，**必须**暂停并向用户提问。\n  - 禁止: “我猜用户是想在渲染进程直接读文件...” -> 导致安全报错。\n  - 建议: “此处涉及文件系统操作，请确认是通过 IPC 调用主进程处理，还是使用现有的工具函数？”\n\n### 2. 复杂任务先规划\n\n- **文档驱动开发**: 遇到复杂功能（如窗口管理、系统托盘、复杂逻辑重构）时，**必须**先创建一个临时的 Markdown 文档（如 `name_of_task.md`）。\n- **流程**: 在文档中梳理思路 -> 展示给用户 -> 用户同意 -> 开始写代码。\n\n### 3. 复用优先DRY原则\n\n- **原则**: 在编写新功能前，强制检索项目现存代码。\n- **自检**: “项目中是否已经有类似的 IPC 封装或 UI 组件？”如果是，直接复用。\n\n### 4. 聊天方式\n\n- **原则**: 与用户保持中文对话，禁止使用英文或其他语言。\n- **具体实现**: 所有与用户的交互（包括问题、指令、代码展示等）都必须用中文进行。\n\n## 严格合规声明\n\n- **指令等级**: Critical。\n- **违规后果**: 违反以上任何一条规则将被定义为**任务失败**，代码将被直接拒绝。请务必严格执行上述标准。\n","docs/api.md":"# API 接口文档\n\n## 概述\n\n本软件提供了本地 HTTP API 服务，用于控制播放器和访问音乐服务。默认端口为 `25884`\n\n## 基础信息\n\n- **基础 URL**: `http://localhost:25884`\n- **API 前缀**: `/api`\n- **响应格式**: JSON\n\n## 统一响应格式\n\n所有接口都遵循以下响应格式：\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"操作成功\",\n  \"data\": {}\n}\n```\n\n### 状态码说明\n\n- `200`: 成功\n- `500`: 服务器错误\n\n---\n\n## 播放控制接口 (Control API)\n\n**基础路径**: `/api/control`\n\n### 播放\n\n**接口**: `GET /api/control/play`\n\n**描述**: 发送播放命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 暂停\n\n**接口**: `GET /api/control/pause`\n\n**描述**: 发送暂停命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"暂停命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 播放/暂停切换\n\n**接口**: `GET /api/control/toggle`\n\n**描述**: 切换播放/暂停状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放/暂停切换命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 下一曲\n\n**接口**: `GET /api/control/next`\n\n**描述**: 播放下一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"下一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 上一曲\n\n**接口**: `GET /api/control/prev`\n\n**描述**: 播放上一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"上一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 获取状态\n\n**接口**: `GET /api/control/status`\n\n**描述**: 获取软件版本、环境数据和连接状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取状态成功\",\n  \"data\": {\n    \"version\": {\n      \"app\": \"3.0.0-beta.6\",\n      \"name\": \"SPlayer\"\n    },\n    \"environment\": {\n      \"platform\": \"win32\",\n      \"arch\": \"x64\",\n      \"nodeVersion\": \"20.x.x\",\n      \"electronVersion\": \"x.x.x\",\n      \"chromeVersion\": \"x.x.x\",\n      \"v8Version\": \"x.x.x\"\n    },\n    \"connected\": true,\n    \"window\": \"available\"\n  }\n}\n```\n\n**响应字段说明**:\n\n- `version.app`: 软件版本号\n- `version.name`: 软件名称\n- `environment.platform`: 操作系统平台 (win32/darwin/linux)\n- `environment.arch`: 系统架构 (x64/arm64)\n- `environment.nodeVersion`: Node.js 版本\n- `environment.electronVersion`: Electron 版本\n- `environment.chromeVersion`: Chrome 版本\n- `environment.v8Version`: V8 引擎版本\n- `connected`: 是否已连接\n- `window`: 窗口状态\n\n---\n\n### 获取当前播放信息\n\n**接口**: `GET /api/control/song-info`\n\n**描述**: 获取当前播放的歌曲信息\n\n> [!WARNING]\n> 请勿频繁调用此接口（如每秒调用一次）来获取播放进度，这会导致软件性能异常。\n> 如需实时获取播放进度和状态，请使用 WebSocket 连接并监听相关事件。\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取当前播放信息成功\",\n  \"data\": {\n    \"playStatus\": \"play\",\n    \"playName\": \"歌曲名\",\n    \"artistName\": \"歌手名\",\n    \"albumName\": \"专辑名\",\n    \"currentTime\": 123.45,\n    \"volume\": 1,\n    \"playRate\": 1,\n    \"id\": 123456,\n    \"name\": \"歌曲名\",\n    \"artists\": \"歌手名\",\n    \"album\": \"专辑名\",\n    \"cover\": \"http://...\",\n    \"duration\": 300,\n    \"lrcData\": [],\n    \"yrcData\": []\n  }\n}\n```\n\n---\n\n## 云音乐 API (Netease API)\n\n**基础路径**: `/api/netease`\n\n### 使用说明\n\n云音乐 API 支持所有 NeteaseCloudMusicApi Enhanced 的接口。接口路径会自动转换为 kebab-case 格式。\n\n**示例**:\n\n- `GET /api/netease/login/cellphone?phone=xxx&password=xxx`\n- `GET /api/netease/user/playlist?uid=xxx`\n- `GET /api/netease/song/detail?ids=xxx`\n\n更多接口请参考 [NeteaseCloudMusicApi Enhanced 文档](https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced)\n\n---\n\n## 解锁 API (Unblock API)\n\n**基础路径**: `/api/unblock`\n\n### 云音乐解锁\n\n**接口**: `GET /api/unblock/netease?id={songId}`\n\n**描述**: 获取网易云音乐解锁后的播放链接\n\n**请求参数**:\n\n- `id` (必需): 歌曲 ID\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 酷我解锁\n\n**接口**: `GET /api/unblock/kuwo?keyword={keyword}`\n\n**描述**: 获取酷我音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 波点解锁\n\n**接口**: `GET /api/unblock/bodian?keyword={keyword}`\n\n**描述**: 获取波点音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n## 全部 API 列表\n\n**接口**: `GET /api`\n\n**描述**: 获取所有 API 模块列表\n\n**响应示例**:\n\n```json\n{\n  \"name\": \"SPlayer API\",\n  \"description\": \"SPlayer API service\",\n  \"author\": \"@imsyy\",\n  \"list\": [\n    {\n      \"name\": \"NeteaseCloudMusicApi\",\n      \"url\": \"/api/netease\"\n    },\n    {\n      \"name\": \"UnblockAPI\",\n      \"url\": \"/api/unblock\"\n    }\n  ]\n}\n```\n\n---\n\n## 错误处理\n\n当接口发生错误时，会返回以下格式：\n\n```json\n{\n  \"code\": 500,\n  \"message\": \"错误描述\",\n  \"data\": null\n}\n```\n\n常见错误：\n\n- `主窗口未找到`: 应用程序主窗口未初始化\n- `播放失败`: 播放操作执行失败\n- `获取状态失败`: 状态获取失败\n\n---\n\n### 使用示例\n\n#### cURL 示例\n\n```bash\n# 播放\ncurl http://localhost:25884/api/control/play\n\n# 暂停\ncurl http://localhost:25884/api/control/pause\n\n# 下一曲\ncurl http://localhost:25884/api/control/next\n\n# 获取状态\ncurl http://localhost:25884/api/control/status\n```\n\n#### JavaScript 示例\n\n```javascript\n// 播放\nfetch(\"http://localhost:25884/api/control/play\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n\n// 获取状态\nfetch(\"http://localhost:25884/api/control/status\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n```\n\n#### Python 示例\n\n```python\nimport requests\n\n# 播放\nresponse = requests.get('http://localhost:25884/api/control/play')\nprint(response.json())\n\n# 获取状态\nresponse = requests.get('http://localhost:25884/api/control/status')\nprint(response.json())\n```\n\n---\n\n## 注意事项\n\n1. 所有接口仅在应用程序运行时可用\n2. HTTP API 默认端口为 `25884`，可在环境变量 `VITE_SERVER_PORT` 中配置\n3. WebSocket API 默认端口为 `25885`，可在应用程序设置中修改\n4. 解锁接口仅供学习使用，请勿用于商业用途\n5. 网易云音乐 API 需要登录后才能使用部分功能\n6. 接口响应时间取决于网络状况和服务器负载\n7. WebSocket 连接支持心跳检测（PING/PONG），建议客户端定期发送心跳以保持连接\n\n---\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/imsyy/SPlayer/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AI 开发助手行为准则\n\n## 项目技术栈与环境\n\n- **核心框架**: Vue 3 + Electron\n- **UI 组件库**: **Naive UI** (严禁混用其他 UI 库)\n- **包管理器**: **严格使用 `pnpm`** (严禁使用 npm/yarn)\n- **开发命令**: `pnpm dev` (预览代码)\n- **代码质量**: 每次任务结束前，必须自动运行 `pnpm lint` 并修复所有问题，确保 0 错误、0 警告后方可交付。\n- **提交之前**: 必须运行 `pnpm build` 和 `pnpm format` 并修复所有问题，确保 0 错误、0 警告后方可提交。\n\n## 代码风格与规范\n\n### 1. 注释规范\n\n- **语言**: 必须使用**中文**。\n- **格式**: 保持简洁，禁止长句、英文长文或带序号的注释。\n  - 正确: `// 监听主进程消息`\n  - 错误: `// 1. listen to main process`, `// this function handles ipc...`\n\n### 2. UI 组件使用 Naive UI\n\n- **原则**: 严禁重复造轮子。所有通用交互必须优先使用 Naive UI 组件。\n- **处理方式**: 如果未找到合适组件，必须先询问用户，禁止擅自手写原生 CSS/HTML 组件。\n  - 正确: 使用 `<n-button type=\"primary\">`, `<n-modal>`, `<n-message-provider>`\n  - 错误: 手写 `<div class=\"my-btn\">` 或引入 Element Plus 等其他库。\n\n### 3. 图标\n\n- **原则**: 优先复用项目 `src/assets/icons` 或现有图标方案。\n- **具体实现**: 严格遵循项目现有的图标组件用法。\n  - 正确: `<SvgIcon :name=\"isLikeAlbum ? 'Favorite' : 'FavoriteBorder'\" />`\n  - 错误: 擅自引入 `xicons` (除非用户明确允许) 或手写 SVG 代码。\n\n### 4. Electron 特性规范\n\n- **进程安全**: 明确代码运行环境（Main vs Renderer）。不要在渲染进程中直接调用不安全的 Node.js API，应优先使用 IPC 通信或 Preload 脚本暴露的 API。\n- **通信规范**: 涉及 IPC 通信时，保持频道命名清晰且常量化。\n\n### 5. 测试与清理\n\n- **临时文件**: 任务过程中生成的临时测试文件（如 `test_lrc.ts`），必须在任务结束前自动删除，严禁推送到代码库。\n\n## 交互与思维链\n\n### 1. 遇到困难多确认\n\n- **原则**: 禁止假设。当遇到不理解的概念（特别是 Electron 的通信逻辑或原生能力调用）时，**必须**暂停并向用户提问。\n  - 禁止: “我猜用户是想在渲染进程直接读文件...” -> 导致安全报错。\n  - 建议: “此处涉及文件系统操作，请确认是通过 IPC 调用主进程处理，还是使用现有的工具函数？”\n\n### 2. 复杂任务先规划\n\n- **文档驱动开发**: 遇到复杂功能（如窗口管理、系统托盘、复杂逻辑重构）时，**必须**先创建一个临时的 Markdown 文档（如 `name_of_task.md`）。\n- **流程**: 在文档中梳理思路 -> 展示给用户 -> 用户同意 -> 开始写代码。\n\n### 3. 复用优先DRY原则\n\n- **原则**: 在编写新功能前，强制检索项目现存代码。\n- **自检**: “项目中是否已经有类似的 IPC 封装或 UI 组件？”如果是，直接复用。\n\n### 4. 聊天方式\n\n- **原则**: 与用户保持中文对话，禁止使用英文或其他语言。\n- **具体实现**: 所有与用户的交互（包括问题、指令、代码展示等）都必须用中文进行。\n\n## 严格合规声明\n\n- **指令等级**: Critical。\n- **违规后果**: 违反以上任何一条规则将被定义为**任务失败**，代码将被直接拒绝。请务必严格执行上述标准。\n","isInternal":false,"tokens":1242,"sizeBytes":3453},{"name":"api.md","path":"docs/api.md","rawUrl":"https://raw.githubusercontent.com/imsyy/SPlayer/HEAD/docs/api.md","title":"docs - API Interface Contract & Specifications","category":"project-spec","format":"markdown","content":"# API 接口文档\n\n## 概述\n\n本软件提供了本地 HTTP API 服务，用于控制播放器和访问音乐服务。默认端口为 `25884`\n\n## 基础信息\n\n- **基础 URL**: `http://localhost:25884`\n- **API 前缀**: `/api`\n- **响应格式**: JSON\n\n## 统一响应格式\n\n所有接口都遵循以下响应格式：\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"操作成功\",\n  \"data\": {}\n}\n```\n\n### 状态码说明\n\n- `200`: 成功\n- `500`: 服务器错误\n\n---\n\n## 播放控制接口 (Control API)\n\n**基础路径**: `/api/control`\n\n### 播放\n\n**接口**: `GET /api/control/play`\n\n**描述**: 发送播放命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 暂停\n\n**接口**: `GET /api/control/pause`\n\n**描述**: 发送暂停命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"暂停命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 播放/暂停切换\n\n**接口**: `GET /api/control/toggle`\n\n**描述**: 切换播放/暂停状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放/暂停切换命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 下一曲\n\n**接口**: `GET /api/control/next`\n\n**描述**: 播放下一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"下一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 上一曲\n\n**接口**: `GET /api/control/prev`\n\n**描述**: 播放上一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"上一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 获取状态\n\n**接口**: `GET /api/control/status`\n\n**描述**: 获取软件版本、环境数据和连接状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取状态成功\",\n  \"data\": {\n    \"version\": {\n      \"app\": \"3.0.0-beta.6\",\n      \"name\": \"SPlayer\"\n    },\n    \"environment\": {\n      \"platform\": \"win32\",\n      \"arch\": \"x64\",\n      \"nodeVersion\": \"20.x.x\",\n      \"electronVersion\": \"x.x.x\",\n      \"chromeVersion\": \"x.x.x\",\n      \"v8Version\": \"x.x.x\"\n    },\n    \"connected\": true,\n    \"window\": \"available\"\n  }\n}\n```\n\n**响应字段说明**:\n\n- `version.app`: 软件版本号\n- `version.name`: 软件名称\n- `environment.platform`: 操作系统平台 (win32/darwin/linux)\n- `environment.arch`: 系统架构 (x64/arm64)\n- `environment.nodeVersion`: Node.js 版本\n- `environment.electronVersion`: Electron 版本\n- `environment.chromeVersion`: Chrome 版本\n- `environment.v8Version`: V8 引擎版本\n- `connected`: 是否已连接\n- `window`: 窗口状态\n\n---\n\n### 获取当前播放信息\n\n**接口**: `GET /api/control/song-info`\n\n**描述**: 获取当前播放的歌曲信息\n\n> [!WARNING]\n> 请勿频繁调用此接口（如每秒调用一次）来获取播放进度，这会导致软件性能异常。\n> 如需实时获取播放进度和状态，请使用 WebSocket 连接并监听相关事件。\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取当前播放信息成功\",\n  \"data\": {\n    \"playStatus\": \"play\",\n    \"playName\": \"歌曲名\",\n    \"artistName\": \"歌手名\",\n    \"albumName\": \"专辑名\",\n    \"currentTime\": 123.45,\n    \"volume\": 1,\n    \"playRate\": 1,\n    \"id\": 123456,\n    \"name\": \"歌曲名\",\n    \"artists\": \"歌手名\",\n    \"album\": \"专辑名\",\n    \"cover\": \"http://...\",\n    \"duration\": 300,\n    \"lrcData\": [],\n    \"yrcData\": []\n  }\n}\n```\n\n---\n\n## 云音乐 API (Netease API)\n\n**基础路径**: `/api/netease`\n\n### 使用说明\n\n云音乐 API 支持所有 NeteaseCloudMusicApi Enhanced 的接口。接口路径会自动转换为 kebab-case 格式。\n\n**示例**:\n\n- `GET /api/netease/login/cellphone?phone=xxx&password=xxx`\n- `GET /api/netease/user/playlist?uid=xxx`\n- `GET /api/netease/song/detail?ids=xxx`\n\n更多接口请参考 [NeteaseCloudMusicApi Enhanced 文档](https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced)\n\n---\n\n## 解锁 API (Unblock API)\n\n**基础路径**: `/api/unblock`\n\n### 云音乐解锁\n\n**接口**: `GET /api/unblock/netease?id={songId}`\n\n**描述**: 获取网易云音乐解锁后的播放链接\n\n**请求参数**:\n\n- `id` (必需): 歌曲 ID\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 酷我解锁\n\n**接口**: `GET /api/unblock/kuwo?keyword={keyword}`\n\n**描述**: 获取酷我音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 波点解锁\n\n**接口**: `GET /api/unblock/bodian?keyword={keyword}`\n\n**描述**: 获取波点音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n## 全部 API 列表\n\n**接口**: `GET /api`\n\n**描述**: 获取所有 API 模块列表\n\n**响应示例**:\n\n```json\n{\n  \"name\": \"SPlayer API\",\n  \"description\": \"SPlayer API service\",\n  \"author\": \"@imsyy\",\n  \"list\": [\n    {\n      \"name\": \"NeteaseCloudMusicApi\",\n      \"url\": \"/api/netease\"\n    },\n    {\n      \"name\": \"UnblockAPI\",\n      \"url\": \"/api/unblock\"\n    }\n  ]\n}\n```\n\n---\n\n## 错误处理\n\n当接口发生错误时，会返回以下格式：\n\n```json\n{\n  \"code\": 500,\n  \"message\": \"错误描述\",\n  \"data\": null\n}\n```\n\n常见错误：\n\n- `主窗口未找到`: 应用程序主窗口未初始化\n- `播放失败`: 播放操作执行失败\n- `获取状态失败`: 状态获取失败\n\n---\n\n### 使用示例\n\n#### cURL 示例\n\n```bash\n# 播放\ncurl http://localhost:25884/api/control/play\n\n# 暂停\ncurl http://localhost:25884/api/control/pause\n\n# 下一曲\ncurl http://localhost:25884/api/control/next\n\n# 获取状态\ncurl http://localhost:25884/api/control/status\n```\n\n#### JavaScript 示例\n\n```javascript\n// 播放\nfetch(\"http://localhost:25884/api/control/play\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n\n// 获取状态\nfetch(\"http://localhost:25884/api/control/status\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n```\n\n#### Python 示例\n\n```python\nimport requests\n\n# 播放\nresponse = requests.get('http://localhost:25884/api/control/play')\nprint(response.json())\n\n# 获取状态\nresponse = requests.get('http://localhost:25884/api/control/status')\nprint(response.json())\n```\n\n---\n\n## 注意事项\n\n1. 所有接口仅在应用程序运行时可用\n2. HTTP API 默认端口为 `25884`，可在环境变量 `VITE_SERVER_PORT` 中配置\n3. WebSocket API 默认端口为 `25885`，可在应用程序设置中修改\n4. 解锁接口仅供学习使用，请勿用于商业用途\n5. 网易云音乐 API 需要登录后才能使用部分功能\n6. 接口响应时间取决于网络状况和服务器负载\n7. WebSocket 连接支持心跳检测（PING/PONG），建议客户端定期发送心跳以保持连接\n\n---\n","isInternal":false,"tokens":2388,"sizeBytes":7039},{"name":"package.json","path":"native/tools/package.json","rawUrl":"https://raw.githubusercontent.com/imsyy/SPlayer/HEAD/native/tools/package.json","title":"tools","category":"anthropic-skill","format":"json","content":"{\n  \"name\": \"tools\",\n  \"version\": \"0.1.0\",\n  \"main\": \"tools.node\",\n  \"types\": \"index.d.ts\",\n  \"napi\": {\n    \"binaryName\": \"tools\"\n  },\n  \"scripts\": {\n    \"build\": \"napi build --release --no-const-enum\",\n    \"build:debug\": \"napi build --no-const-enum\"\n  },\n  \"devDependencies\": {\n    \"@napi-rs/cli\": \"^3\"\n  }\n}\n","frontmatter":{"name":"tools","version":"0.1.0","main":"tools.node","types":"index.d.ts","napi":{"binaryName":"tools"},"scripts":{"build":"napi build --release --no-const-enum","build:debug":"napi build --no-const-enum"},"devDependencies":{"@napi-rs/cli":"^3"}},"isInternal":false,"tokens":113,"sizeBytes":310},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/imsyy/SPlayer/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nSPlayer is a desktop music player built with **Electron + Vue 3 + TypeScript**. It uses Naive UI for components, Pinia for state management, and integrates with NetEase Cloud Music API, Last.fm, and Subsonic/Navidrome streaming services. Native Rust modules provide OS-level features (taskbar lyrics on Windows, MPRIS on Linux, SMTC on Windows, Discord RPC).\n\n## Commands\n\n```bash\npnpm dev                # Start dev environment (builds native modules + launches Electron)\npnpm build              # Full production build (typecheck + electron-vite build)\npnpm build:win          # Package for Windows\npnpm build:mac          # Package for macOS\npnpm build:linux        # Package for Linux\npnpm lint               # ESLint (--max-warnings=0, zero tolerance)\npnpm format             # Prettier\npnpm typecheck          # Full TypeScript check (node + web)\npnpm typecheck:node     # Main process + preload TypeScript check\npnpm typecheck:web      # Renderer process TypeScript check\n```\n\nSet `SKIP_NATIVE_BUILD=true` to skip Rust native module compilation during dev.\n\n## Architecture\n\n### Process Model (Electron)\n\n- **Main process** (`electron/main/`): Window management, IPC handlers, SQLite database, system tray, global shortcuts, Fastify API server, native module integration\n- **Preload** (`electron/preload/`): Context bridge exposing `window.api.store` and `window.logger` to renderer\n- **Renderer** (`src/`): Vue 3 SPA — the UI\n\n### IPC Layer\n\n18 IPC modules in `electron/main/ipc/` handle all main↔renderer communication: `ipc-cache`, `ipc-file`, `ipc-lyric`, `ipc-media`, `ipc-mpv`, `ipc-socket`, `ipc-store`, `ipc-taskbar`, `ipc-tray`, `ipc-window`, `ipc-system`, `ipc-shortcut`, `ipc-update`, `ipc-protocol`, `ipc-mac-statusbar`, `ipc-thumbar`, `ipc-renderer-log`.\n\n### Renderer Architecture (`src/`)\n\n- **Stores** (`stores/`): Pinia with persistedstate — `data` (songs/user), `status` (playback), `setting` (config), `local` (local music), `music`, `streaming`, `shortcut`\n- **Core** (`core/`): `audio-player/` (playback engine), `automix/`, `player/` (state), `resource/` (caching)\n- **API** (`api/`): Axios-based, organized by domain (song, playlist, login, streaming, lastfm)\n- **Composables** (`composables/`): `useInit`, `useSongMenu`, `useQualityControl`, etc.\n- **Components** (`components/`): AMLL (lyrics), Card, Common, Global, Layout, List, Menu, Modal, Player, Search, Setting, UI\n\n### Native Modules (`native/`)\n\nRust-based, built via `scripts/build-native.ts`:\n\n- `taskbar-lyric` — Windows taskbar lyrics display\n- `external-media-integration` — OS media integration\n- `smtc-for-splayer` — Windows System Media Transport Controls\n- `mpris-for-splayer` — Linux MPRIS support\n- `discord-rpc-for-splayer` — Discord Rich Presence\n- `ferrous-opencc-wasm` — Chinese character conversion (WASM)\n\n### Embedded Server\n\n`electron/server/` runs a Fastify instance (port 25884 default) wrapping NetEase Cloud Music API, proxied via `/api` in dev.\n\n## Path Aliases\n\n```\n@/       → src/\n@emi/    → native/external-media-integration\n@shared/ → src/types/shared\n@opencc/ → native/ferrous-opencc-wasm/pkg\n@native/ → native/\n```\n\n## Code Conventions\n\n- **Language**: Comments and commit messages in Chinese\n- **Vue**: Composition API with `<script setup>`, TypeScript throughout\n- **Auto-imports**: Vue, vue-router, @vueuse/core, and naive-ui composables are auto-imported (no explicit imports needed)\n- **Naive UI components**: Auto-resolved via `unplugin-vue-components`\n- **Unused variables**: Prefix with `_` to suppress lint warnings\n- **Prettier**: Double quotes, trailing commas, 2-space indent, 100 char width\n- **Workers**: Heavy computation (audio analysis) runs in worker threads (`electron/main/workers/`)\n- **TypeScript**: Composite project — `tsconfig.node.json` (main/preload/scripts) and `tsconfig.web.json` (renderer)\n","isInternal":false,"tokens":1033,"sizeBytes":4010}],"systemPromptSnippet":"<yakaai_skills repo=\"imsyy/SPlayer\">\n<!-- File: AGENTS.md (Tokens: ~1242 | Category: root-instruction) -->\n# AI 开发助手行为准则\n\n## 项目技术栈与环境\n\n- **核心框架**: Vue 3 + Electron\n- **UI 组件库**: **Naive UI** (严禁混用其他 UI 库)\n- **包管理器**: **严格使用 `pnpm`** (严禁使用 npm/yarn)\n- **开发命令**: `pnpm dev` (预览代码)\n- **代码质量**: 每次任务结束前，必须自动运行 `pnpm lint` 并修复所有问题，确保 0 错误、0 警告后方可交付。\n- **提交之前**: 必须运行 `pnpm build` 和 `pnpm format` 并修复所有问题，确保 0 错误、0 警告后方可提交。\n\n## 代码风格与规范\n\n### 1. 注释规范\n\n- **语言**: 必须使用**中文**。\n- **格式**: 保持简洁，禁止长句、英文长文或带序号的注释。\n  - 正确: `// 监听主进程消息`\n  - 错误: `// 1. listen to main process`, `// this function handles ipc...`\n\n### 2. UI 组件使用 Naive UI\n\n- **原则**: 严禁重复造轮子。所有通用交互必须优先使用 Naive UI 组件。\n- **处理方式**: 如果未找到合适组件，必须先询问用户，禁止擅自手写原生 CSS/HTML 组件。\n  - 正确: 使用 `<n-button type=\"primary\">`, `<n-modal>`, `<n-message-provider>`\n  - 错误: 手写 `<div class=\"my-btn\">` 或引入 Element Plus 等其他库。\n\n### 3. 图标\n\n- **原则**: 优先复用项目 `src/assets/icons` 或现有图标方案。\n- **具体实现**: 严格遵循项目现有的图标组件用法。\n  - 正确: `<SvgIcon :name=\"isLikeAlbum ? 'Favorite' : 'FavoriteBorder'\" />`\n  - 错误: 擅自引入 `xicons` (除非用户明确允许) 或手写 SVG 代码。\n\n### 4. Electron 特性规范\n\n- **进程安全**: 明确代码运行环境（Main vs Renderer）。不要在渲染进程中直接调用不安全的 Node.js API，应优先使用 IPC 通信或 Preload 脚本暴露的 API。\n- **通信规范**: 涉及 IPC 通信时，保持频道命名清晰且常量化。\n\n### 5. 测试与清理\n\n- **临时文件**: 任务过程中生成的临时测试文件（如 `test_lrc.ts`），必须在任务结束前自动删除，严禁推送到代码库。\n\n## 交互与思维链\n\n### 1. 遇到困难多确认\n\n- **原则**: 禁止假设。当遇到不理解的概念（特别是 Electron 的通信逻辑或原生能力调用）时，**必须**暂停并向用户提问。\n  - 禁止: “我猜用户是想在渲染进程直接读文件...” -> 导致安全报错。\n  - 建议: “此处涉及文件系统操作，请确认是通过 IPC 调用主进程处理，还是使用现有的工具函数？”\n\n### 2. 复杂任务先规划\n\n- **文档驱动开发**: 遇到复杂功能（如窗口管理、系统托盘、复杂逻辑重构）时，**必须**先创建一个临时的 Markdown 文档（如 `name_of_task.md`）。\n- **流程**: 在文档中梳理思路 -> 展示给用户 -> 用户同意 -> 开始写代码。\n\n### 3. 复用优先DRY原则\n\n- **原则**: 在编写新功能前，强制检索项目现存代码。\n- **自检**: “项目中是否已经有类似的 IPC 封装或 UI 组件？”如果是，直接复用。\n\n### 4. 聊天方式\n\n- **原则**: 与用户保持中文对话，禁止使用英文或其他语言。\n- **具体实现**: 所有与用户的交互（包括问题、指令、代码展示等）都必须用中文进行。\n\n## 严格合规声明\n\n- **指令等级**: Critical。\n- **违规后果**: 违反以上任何一条规则将被定义为**任务失败**，代码将被直接拒绝。请务必严格执行上述标准。\n\n<!-- File: docs/api.md (Tokens: ~2388 | Category: project-spec) -->\n# API 接口文档\n\n## 概述\n\n本软件提供了本地 HTTP API 服务，用于控制播放器和访问音乐服务。默认端口为 `25884`\n\n## 基础信息\n\n- **基础 URL**: `http://localhost:25884`\n- **API 前缀**: `/api`\n- **响应格式**: JSON\n\n## 统一响应格式\n\n所有接口都遵循以下响应格式：\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"操作成功\",\n  \"data\": {}\n}\n```\n\n### 状态码说明\n\n- `200`: 成功\n- `500`: 服务器错误\n\n---\n\n## 播放控制接口 (Control API)\n\n**基础路径**: `/api/control`\n\n### 播放\n\n**接口**: `GET /api/control/play`\n\n**描述**: 发送播放命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 暂停\n\n**接口**: `GET /api/control/pause`\n\n**描述**: 发送暂停命令\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"暂停命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 播放/暂停切换\n\n**接口**: `GET /api/control/toggle`\n\n**描述**: 切换播放/暂停状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"播放/暂停切换命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 下一曲\n\n**接口**: `GET /api/control/next`\n\n**描述**: 播放下一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"下一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 上一曲\n\n**接口**: `GET /api/control/prev`\n\n**描述**: 播放上一首歌曲\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"上一曲命令已发送\",\n  \"data\": null\n}\n```\n\n---\n\n### 获取状态\n\n**接口**: `GET /api/control/status`\n\n**描述**: 获取软件版本、环境数据和连接状态\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取状态成功\",\n  \"data\": {\n    \"version\": {\n      \"app\": \"3.0.0-beta.6\",\n      \"name\": \"SPlayer\"\n    },\n    \"environment\": {\n      \"platform\": \"win32\",\n      \"arch\": \"x64\",\n      \"nodeVersion\": \"20.x.x\",\n      \"electronVersion\": \"x.x.x\",\n      \"chromeVersion\": \"x.x.x\",\n      \"v8Version\": \"x.x.x\"\n    },\n    \"connected\": true,\n    \"window\": \"available\"\n  }\n}\n```\n\n**响应字段说明**:\n\n- `version.app`: 软件版本号\n- `version.name`: 软件名称\n- `environment.platform`: 操作系统平台 (win32/darwin/linux)\n- `environment.arch`: 系统架构 (x64/arm64)\n- `environment.nodeVersion`: Node.js 版本\n- `environment.electronVersion`: Electron 版本\n- `environment.chromeVersion`: Chrome 版本\n- `environment.v8Version`: V8 引擎版本\n- `connected`: 是否已连接\n- `window`: 窗口状态\n\n---\n\n### 获取当前播放信息\n\n**接口**: `GET /api/control/song-info`\n\n**描述**: 获取当前播放的歌曲信息\n\n> [!WARNING]\n> 请勿频繁调用此接口（如每秒调用一次）来获取播放进度，这会导致软件性能异常。\n> 如需实时获取播放进度和状态，请使用 WebSocket 连接并监听相关事件。\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"message\": \"获取当前播放信息成功\",\n  \"data\": {\n    \"playStatus\": \"play\",\n    \"playName\": \"歌曲名\",\n    \"artistName\": \"歌手名\",\n    \"albumName\": \"专辑名\",\n    \"currentTime\": 123.45,\n    \"volume\": 1,\n    \"playRate\": 1,\n    \"id\": 123456,\n    \"name\": \"歌曲名\",\n    \"artists\": \"歌手名\",\n    \"album\": \"专辑名\",\n    \"cover\": \"http://...\",\n    \"duration\": 300,\n    \"lrcData\": [],\n    \"yrcData\": []\n  }\n}\n```\n\n---\n\n## 云音乐 API (Netease API)\n\n**基础路径**: `/api/netease`\n\n### 使用说明\n\n云音乐 API 支持所有 NeteaseCloudMusicApi Enhanced 的接口。接口路径会自动转换为 kebab-case 格式。\n\n**示例**:\n\n- `GET /api/netease/login/cellphone?phone=xxx&password=xxx`\n- `GET /api/netease/user/playlist?uid=xxx`\n- `GET /api/netease/song/detail?ids=xxx`\n\n更多接口请参考 [NeteaseCloudMusicApi Enhanced 文档](https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced)\n\n---\n\n## 解锁 API (Unblock API)\n\n**基础路径**: `/api/unblock`\n\n### 云音乐解锁\n\n**接口**: `GET /api/unblock/netease?id={songId}`\n\n**描述**: 获取网易云音乐解锁后的播放链接\n\n**请求参数**:\n\n- `id` (必需): 歌曲 ID\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 酷我解锁\n\n**接口**: `GET /api/unblock/kuwo?keyword={keyword}`\n\n**描述**: 获取酷我音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n### 波点解锁\n\n**接口**: `GET /api/unblock/bodian?keyword={keyword}`\n\n**描述**: 获取波点音乐解锁后的播放链接\n\n**请求参数**:\n\n- `keyword` (必需): 搜索关键词（歌曲名-歌手名）\n- `songName` (可选): 歌曲名称，用于匹配校验\n- `artist` (可选): 歌手名称，用于匹配校验\n\n**响应示例**:\n\n```json\n{\n  \"code\": 200,\n  \"url\": \"https://...\"\n}\n```\n\n---\n\n## 全部 API 列表\n\n**接口**: `GET /api`\n\n**描述**: 获取所有 API 模块列表\n\n**响应示例**:\n\n```json\n{\n  \"name\": \"SPlayer API\",\n  \"description\": \"SPlayer API service\",\n  \"author\": \"@imsyy\",\n  \"list\": [\n    {\n      \"name\": \"NeteaseCloudMusicApi\",\n      \"url\": \"/api/netease\"\n    },\n    {\n      \"name\": \"UnblockAPI\",\n      \"url\": \"/api/unblock\"\n    }\n  ]\n}\n```\n\n---\n\n## 错误处理\n\n当接口发生错误时，会返回以下格式：\n\n```json\n{\n  \"code\": 500,\n  \"message\": \"错误描述\",\n  \"data\": null\n}\n```\n\n常见错误：\n\n- `主窗口未找到`: 应用程序主窗口未初始化\n- `播放失败`: 播放操作执行失败\n- `获取状态失败`: 状态获取失败\n\n---\n\n### 使用示例\n\n#### cURL 示例\n\n```bash\n# 播放\ncurl http://localhost:25884/api/control/play\n\n# 暂停\ncurl http://localhost:25884/api/control/pause\n\n# 下一曲\ncurl http://localhost:25884/api/control/next\n\n# 获取状态\ncurl http://localhost:25884/api/control/status\n```\n\n#### JavaScript 示例\n\n```javascript\n// 播放\nfetch(\"http://localhost:25884/api/control/play\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n\n// 获取状态\nfetch(\"http://localhost:25884/api/control/status\")\n  .then((res) => res.json())\n  .then((data) => console.log(data));\n```\n\n#### Python 示例\n\n```python\nimport requests\n\n# 播放\nresponse = requests.get('http://localhost:25884/api/control/play')\nprint(response.json())\n\n# 获取状态\nresponse = requests.get('http://localhost:25884/api/control/status')\nprint(response.json())\n```\n\n---\n\n## 注意事项\n\n1. 所有接口仅在应用程序运行时可用\n2. HTTP API 默认端口为 `25884`，可在环境变量 `VITE_SERVER_PORT` 中配置\n3. WebSocket API 默认端口为 `25885`，可在应用程序设置中修改\n4. 解锁接口仅供学习使用，请勿用于商业用途\n5. 网易云音乐 API 需要登录后才能使用部分功能\n6. 接口响应时间取决于网络状况和服务器负载\n7. WebSocket 连接支持心跳检测（PING/PONG），建议客户端定期发送心跳以保持连接\n\n---\n\n<!-- File: native/tools/package.json (Tokens: ~113 | Category: anthropic-skill) -->\n{\n  \"name\": \"tools\",\n  \"version\": \"0.1.0\",\n  \"main\": \"tools.node\",\n  \"types\": \"index.d.ts\",\n  \"napi\": {\n    \"binaryName\": \"tools\"\n  },\n  \"scripts\": {\n    \"build\": \"napi build --release --no-const-enum\",\n    \"build:debug\": \"napi build --no-const-enum\"\n  },\n  \"devDependencies\": {\n    \"@napi-rs/cli\": \"^3\"\n  }\n}\n\n<!-- File: CLAUDE.md (Tokens: ~1033 | Category: claude-rule) -->\n# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nSPlayer is a desktop music player built with **Electron + Vue 3 + TypeScript**. It uses Naive UI for components, Pinia for state management, and integrates with NetEase Cloud Music API, Last.fm, and Subsonic/Navidrome streaming services. Native Rust modules provide OS-level features (taskbar lyrics on Windows, MPRIS on Linux, SMTC on Windows, Discord RPC).\n\n## Commands\n\n```bash\npnpm dev                # Start dev environment (builds native modules + launches Electron)\npnpm build              # Full production build (typecheck + electron-vite build)\npnpm build:win          # Package for Windows\npnpm build:mac          # Package for macOS\npnpm build:linux        # Package for Linux\npnpm lint               # ESLint (--max-warnings=0, zero tolerance)\npnpm format             # Prettier\npnpm typecheck          # Full TypeScript check (node + web)\npnpm typecheck:node     # Main process + preload TypeScript check\npnpm typecheck:web      # Renderer process TypeScript check\n```\n\nSet `SKIP_NATIVE_BUILD=true` to skip Rust native module compilation during dev.\n\n## Architecture\n\n### Process Model (Electron)\n\n- **Main process** (`electron/main/`): Window management, IPC handlers, SQLite database, system tray, global shortcuts, Fastify API server, native module integration\n- **Preload** (`electron/preload/`): Context bridge exposing `window.api.store` and `window.logger` to renderer\n- **Renderer** (`src/`): Vue 3 SPA — the UI\n\n### IPC Layer\n\n18 IPC modules in `electron/main/ipc/` handle all main↔renderer communication: `ipc-cache`, `ipc-file`, `ipc-lyric`, `ipc-media`, `ipc-mpv`, `ipc-socket`, `ipc-store`, `ipc-taskbar`, `ipc-tray`, `ipc-window`, `ipc-system`, `ipc-shortcut`, `ipc-update`, `ipc-protocol`, `ipc-mac-statusbar`, `ipc-thumbar`, `ipc-renderer-log`.\n\n### Renderer Architecture (`src/`)\n\n- **Stores** (`stores/`): Pinia with persistedstate — `data` (songs/user), `status` (playback), `setting` (config), `local` (local music), `music`, `streaming`, `shortcut`\n- **Core** (`core/`): `audio-player/` (playback engine), `automix/`, `player/` (state), `resource/` (caching)\n- **API** (`api/`): Axios-based, organized by domain (song, playlist, login, streaming, lastfm)\n- **Composables** (`composables/`): `useInit`, `useSongMenu`, `useQualityControl`, etc.\n- **Components** (`components/`): AMLL (lyrics), Card, Common, Global, Layout, List, Menu, Modal, Player, Search, Setting, UI\n\n### Native Modules (`native/`)\n\nRust-based, built via `scripts/build-native.ts`:\n\n- `taskbar-lyric` — Windows taskbar lyrics display\n- `external-media-integration` — OS media integration\n- `smtc-for-splayer` — Windows System Media Transport Controls\n- `mpris-for-splayer` — Linux MPRIS support\n- `discord-rpc-for-splayer` — Discord Rich Presence\n- `ferrous-opencc-wasm` — Chinese character conversion (WASM)\n\n### Embedded Server\n\n`electron/server/` runs a Fastify instance (port 25884 default) wrapping NetEase Cloud Music API, proxied via `/api` in dev.\n\n## Path Aliases\n\n```\n@/       → src/\n@emi/    → native/external-media-integration\n@shared/ → src/types/shared\n@opencc/ → native/ferrous-opencc-wasm/pkg\n@native/ → native/\n```\n\n## Code Conventions\n\n- **Language**: Comments and commit messages in Chinese\n- **Vue**: Composition API with `<script setup>`, TypeScript throughout\n- **Auto-imports**: Vue, vue-router, @vueuse/core, and naive-ui composables are auto-imported (no explicit imports needed)\n- **Naive UI components**: Auto-resolved via `unplugin-vue-components`\n- **Unused variables**: Prefix with `_` to suppress lint warnings\n- **Prettier**: Double quotes, trailing commas, 2-space indent, 100 char width\n- **Workers**: Heavy computation (audio analysis) runs in worker threads (`electron/main/workers/`)\n- **TypeScript**: Composite project — `tsconfig.node.json` (main/preload/scripts) and `tsconfig.web.json` (renderer)\n</yakaai_skills>"}