Bilibili Evolved 仓库开发指南:面向编码 Agent 的 AGENTS.md 深度解读与实践
2026/9/19 19:13:03 网站建设 项目流程

Bilibili Evolved 仓库开发指南:面向编码 Agent 的 AGENTS.md 深度解读与实践

【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved

Bilibili Evolved 是一个基于 Web 前端技术构建的哔哩哔哩增强油猴脚本(userscript)。本文以仓库根目录的 AGENTS.md 为核心骨架,结合 CONTRIBUTING.md、开发服务源码与真实组件实现,系统讲解该仓库的项目结构、开发环境搭建、dev-server 调试协议、组件与插件编写规范、代码风格、验证流程以及分支与提交约定。阅读本文后,你将能够独立地在本地完成该仓库的开发环境配置,正确区分"组件"与"插件"的定位,使用命令行与 WebSocket 驱动 dev-server 完成功能编译、监听、调试与脚手架创建,并通过pnpm run typepnpm run lint-check等命令通过代码检查,最终以preview-features/preview-fixes为基准确发起 Pull Request。

AGENTS.md 在仓库中的定位

AGENTS.md 是给编码 Agent 的仓库级专项指导文件。它在文档体系中处于"第二步"的位置:先阅读 CONTRIBUTING.md 了解贡献全流程,再把 AGENTS.md 作为实现与验证阶段的实操清单

两者的分工可以概括为:

  • CONTRIBUTING.md:面向人类的完整贡献指南,覆盖环境搭建、Tampermonkey 本地调试脚本配置、本体/组件/插件的开发与新增流程、可用 API 资源、代码检查与 PR 提交。
  • AGENTS.md:面向 AI 编码 Agent 的精简检查单,用更结构化的条目把项目结构、命令、规范、验证标准浓缩成可执行的约束。

因此,任何在本仓库执行修改任务的 Agent,都应先通过 CONTRIBUTING.md 建立全局认知,再逐条对照 AGENTS.md 的清单落地实现。

项目结构:理解三个代码区的职责边界

AGENTS.md 首先明确了仓库的顶层布局,核心是理解"本体"与"功能"分离的架构:

  • src/:油猴脚本本体(userscript core),包含内置组件、共享运行时 API、设置 UI,以及随主脚本一起发布的代码。开发时会在dist/下生成开发版脚本bilibili-evolved.dev.user.js
  • registry/lib/components/:可安装组件(installable components)源码。新组件应放入对应的类别目录(如feeds/live/style/touch/utils/video/),并以index.ts作为 webpack 编译入口——webpack 配置会搜索所有index.ts作为组件入口,该文件名不可更改。
  • registry/lib/plugins/:插件源码。当某个功能只有作为另一个组件的扩展才有意义时,应实现为插件而非组件。
  • registry/lib/docs/third-party.ts:第三方组件登记入口。希望保持独立于主仓库的组件,通过向该文件中的数组追加信息来注册,而不是把外部组件注册逻辑混入仓库内源码修改。
  • dist/registry/dist/:构建产物。开发分支不应保留生成的 dist 文件;previewmastermaster-cdn等发布输出分支的产物由 CI 构建产生。
  • doc/features/:由元数据生成的功能文档输出。仅在任务明确涉及生成文档或发布准备时才更新,普通功能或修复 PR 中不要手动修改。

从实现看,src/components/下也有一部分组件(如define.tstypes.ts),这些是内置组件,无法独立安装/卸载;真正可独立安装卸载的组件都在registry/lib/components/下。这一区分是理解"本体 vs 功能"的关键。

开发环境搭建与常用命令

环境前提与依赖安装

根据 CONTRIBUTING.md,环境需要 Node.js(>= 14.0)、Visual Studio Code 与 pnpm(>= 8.9.0)。AGENTS.md 强调包管理器是pnpm(根目录 package.json 中packageManager锁定为pnpm@10.3.0),并给出两条安装命令:

# 安装根目录依赖(本体) pnpm install # 构建 registry 功能时需要安装 registry 依赖 cd registry && pnpm install

当对任务命令存疑时,以.vscode/tasks.json中定义的 VS Code Tasks 为本地任务命令的事实来源(npm scripts 仅用于 CI)。

常用命令速查

AGENTS.md 列出的常用命令如下,它们在根目录 package.json 的scripts中均有对应实现:

# TypeScript 类型检查(对应 scripts.type: tsc -p tsconfig.type-check.json --noEmit) pnpm run type # ESLint 风格检查(对应 scripts.lint-check: eslint . --ext .ts,.vue) pnpm run lint-check # 启动开发服务(核心 watcher + WebSocket + HTTP) pnpm tsx dev-tools/dev-server/index.ts # 查询当前被监听的功能会话 pnpm tsx dev-tools/dev-server/command.ts sessions # 优雅关闭开发服务 pnpm tsx dev-tools/dev-server/command.ts shutdown

其中pnpm tsx dev-tools/dev-server/index.ts的启动逻辑见 dev-tools/dev-server/index.ts:依次启动 HTTP 服务器、核心 watcher(自动编译开发版本体)与 WebSocket 服务器。启动成功后终端会输出类似:

DevServer 已启动, 端口: 23333 本体编译中... (...可能有一长串输出) 本体已编译: (一段 hash)

Dev Server 深入:HTTP、WebSocket 与 CLI 三条通道

开发服务是本地调试的核心设施,dev-tools/dev-server/README.md 给出了完整协议说明。它通过三条通道协同工作:

HTTP:静态资源与虚拟编译 URL

HTTP 服务器只为本体产物服务根目录静态文件:dist/*映射到核心 userscript 输出。

registry/dist/components/<id>.jsregistry/dist/plugins/<id>.js虚拟输出 URL:当内存中缺少对应产物时触发按需编译(build-on-request),随后从内存返回编译结果;其他/registry/*路径不从磁盘提供。HTTP 不暴露控制 API,所有控制能力都走 WebSocket。

WebSocket:命令与事件控制面

默认地址为ws://localhost:23333(端口见 dev-tools/dev-server/config.ts 中的默认值23333)。客户端可发送以下命令载荷(完整类型定义见 dev-tools/dev-server/payload.ts):

{ "type": "queryFeatureSessions" }
{ "type": "shutdownServer", "requestId": "..." }
{ "type": "buildFeature", "kind": "component", "id": "style/hide/banner", "requestId": "..." }
{ "type": "startFeatureSession", "kind": "plugin", "id": "video/player/speed", "requestId": "..." }
{ "type": "stopFeatureSession", "kind": "component", "id": "style/hide/banner", "requestId": "..." }
{ "type": "startDebugFeature", "kind": "component", "id": "style/hide/banner", "targetClientId": "dev-client-1", "requestId": "..." }
{ "type": "createFeature", "kind": "component", "id": "style/my-feature", "name": "myFeature", "displayName": "My Feature", "authorName": "Author Name", "authorLink": "https://example.com", "description": "Feature description.", "requestId": "..." }

服务器侧会推送以下事件:

  • serverReady:连接建立时的初始事件,携带clientId与当前激活的featureSessions
  • featureSessionsChanged:被监听的功能路径发生变化。
  • itemUpdate:被监听功能编译完成,DevClient 应进行更新。
  • featureBuilt:显式构建或监听构建完成。
  • featureBuildFailed:显式构建失败。
  • serverStop:服务器正在关闭,DevClient 应恢复 dev URL 并关闭 socket。
  • commandResult:针对带requestId命令的响应。

CLI:command.ts 命令行客户端

不需要手写 WebSocket 客户端时,直接使用命令客户端(开发服务运行期间):

pnpm tsx dev-tools/dev-server/command.ts sessions pnpm tsx dev-tools/dev-server/command.ts build component style/hide/banner pnpm tsx dev-tools/dev-server/command.ts watch plugin video/player/speed pnpm tsx dev-tools/dev-server/command.ts stop component style/hide/banner pnpm tsx dev-tools/dev-server/command.ts start-debug component style/hide/banner dev-client-1 pnpm tsx dev-tools/dev-server/command.ts stop-debug component style/hide/banner pnpm tsx dev-tools/dev-server/command.ts shutdown

各命令的参数细节在 dev-tools/dev-server/command.ts 中有完整实现与用法输出:

  • build <component|plugin> <id> [development|production]:单功能编译,第二个可选参数决定 development 还是 production 模式,其余值一律视为 development。
  • watch <component|plugin> <id>:启动监听会话,代码改动后自动重编译。
  • stop <component|plugin> <id>:停止监听会话。
  • start-debug <component|plugin> <id> [targetClientId]:将编译产物定向推送给指定clientId的 DevClient 进行页面调试。
  • stop-debug <component|plugin> <id>:结束调试会话。
  • sessions:列出当前所有被监听的功能会话。
  • shutdown:优雅关闭整个开发服务。
  • create <component|plugin> <id> <name> <displayName> <authorName> [authorLink] [description]:创建功能脚手架(见下文)。

shutdown命令会先响应命令客户端,广播serverStop,再依次关闭核心 watcher、功能 watcher、WebSocket 连接与 HTTP 服务器,因此完成开发后应使用它退出,而不是手动结束 Node.js 子进程。

配置项:dev/dev-server.json

dev-tools/dev-server/config.ts 展示了配置合并逻辑:默认值{ port: 23333, maxWatchers: 16 }与可选文件dev/dev-server.json中的配置做浅合并,后者可覆盖前者。也就是说,可以通过在仓库根目录创建dev/dev-server.json自定义端口与最大 watcher 数,例如:

{ "port": 23333, "maxWatchers": 16 }

组件与插件编写规范

AGENTS.md 对组件与插件的编写给出了明确约束,下面逐条结合源码展开。

用 defineComponentMetadata 定义组件

组件必须通过defineComponentMetadata定义并导出component对象。src/components/define.ts 中该函数只是一个泛型恒等函数,作用是让 TypeScript 根据ComponentMetadata类型对元数据做静态校验。一个真实的组件示例是 registry/lib/components/feeds/filter/index.ts 中的feedsFilter(动态过滤器):

export const component = defineComponentMetadata({ name: 'feedsFilter', displayName: '动态过滤器', entry, tags: [componentsTags.feeds], options, reload: () => document.body.classList.remove('disable-feeds-filter'), unload: () => document.body.classList.add('disable-feeds-filter'), urlInclude: [/^https:\/\/t\.bilibili\.com\/$/], plugin: feedsFilterPlugin, })

插件则遵循PluginMetadata接口,导出plugin对象(src/plugins/plugin.ts),例如setup函数作为插件初始化入口。AGENTS.md 要求:registry/lib/plugins/下的代码遵循既有插件定义模式。

关键元数据与生命周期约定

  • author必填:新组件必须包含author元数据,通常是 GitHub 用户名与主页地址;如需注明 AI 辅助开发,author可以是数组,追加 AI 名称与官网。
  • 命名规范name应具体且使用 camelCase;displayName与选项名应清晰描述功能,避免通用标签。
  • index.md即描述:若组件带index.md,编译时其内容会自动注入description,除非该组件的既有模式要求,否则不要在元数据中重复编写相同描述。
  • 页面匹配用urlInclude/urlExclude:不要在手写entry中重复进行页面判断。上述动态过滤器就用urlInclude: [/^https:\/\/t\.bilibili\.com\/$/]限定仅作用于动态首页。
  • entry只做启动必要工作:保持entry专注于组件启动时必须完成的事。
  • 清理逻辑放unload:不要依赖entry的返回值做清理。需要支持"关闭/重新开启"实时生效的组件,必须让reloadunload成对出现。
  • 选项定义:遵循既有defineOptionsMetadataoptions模式(见 src/components/types.ts 中OptionsMetadata类型),让默认值、标签与校验器与元数据保持一处定义;互斥的多选布尔项应建模为单一选项(enum 或下拉)。

样式规范

  • 固定的组件样式放入 SCSS 文件,不要在业务逻辑中拼接样式字符串。
  • 使用instantStylesstyledComponentEntrytoggleStyle,保证样式只在预期时机生效。
  • 编写 SCSS 前先查找共享 Sass 文件:ui/_common.scss可通过@import "common"引入,提供全屏、居中之类的通用 mixin。
  • 当设置需要控制 CSS 时,优先在htmlbody上切换 class,再针对该 class 编写 SCSS。

创建新功能的脚手架

create命令会调用 dev-tools/dev-server/scaffold.ts 中的createFeature:校验 ID 合法性(拒绝空值、以/开头、包含..或绝对路径),在registry/lib/components/<id>(或registry/lib/plugins/<id>)下创建目录,并生成index.tsindex.md。生成的组件模板自带defineComponentMetadata骨架、tags(自动取 ID 首段映射为分类标签)、author字段;插件模板则导出带setupPluginMetadata。因此,新增功能的正确姿势是:先create生成骨架,再填充业务逻辑与选项。

代码风格约定

AGENTS.md 的 Code Style 章节对代码风格提出具体要求,均与仓库的 ESLint(airbnb-base 扩展)与 Prettier 配置对应:

  • 遵循仓库的 ESLint 与 Prettier 配置。
  • 除既有 ESLint overrides 覆盖的文件(如 Vue 单文件组件与构建相关文件)外,使用具名导出
  • 控制流语句体保持花括号包裹。
  • 保留所修改代码周边的既有 TypeScript、Vue 2 与 SCSS 约定(项目当前基于 Vue 2.7,见 package.json 依赖)。
  • 避免不必要的防御性分支、空错误处理、重复状态与一次性抽象。
  • 优先复用既有的 Bilibili API 封装、请求辅助、设置辅助、observer 工具、样式工具与 UI 组件,而不是重新实现等价行为。
  • 能通过稳定 Bilibili API 与既有封装获得数据时,不要读取页面内部全局变量或框架内部实现。
  • DOM 选择器作用域应限定在最近的稳定父类或页面区域,避免命中无关 B 站 UI 的宽泛选择器。
  • 名称与类型必须与行为一致:若函数开始返回更宽泛的形状,应更新类型与名称,而不是重载一个误导性契约。
  • 谨慎对待数据单位与 API 失败态:不要把失败请求当作成功值缓存;字节、比特、数量、ID 与 URL 的语义要保持明确。

验证流程:本地检查与 CI 生产构建的分工

AGENTS.md 要求按变更的风险与范围选择验证方式:

  • 类型检查pnpm run type
  • 风格检查pnpm run lint-check(可自动修复的问题也可运行pnpm run lint)。
  • 本体核心修改:使用 dev-server 的核心 watcher,它会自动编译开发版本体。
  • registry 功能修改:dev-server 运行期间执行pnpm tsx dev-tools/dev-server/command.ts build <component|plugin> <id>
  • dev-server 自身 TypeScript 修改pnpm exec tsc -p dev-tools/dev-server/tsconfig.json
  • 浏览器行为验证:用本地 userscript 在真实浏览器中验证改动后的功能。
  • 依赖 API 形状或 B 站灰度变化:记录实际自测的页面与账号状态。

此外,CONTRIBUTING.md 补充了 PR 文件检查命令pnpm run check-pr-files(对应 dev-tools/pr-check/ 实现),用于发现提交构建产物、手动编辑生成的功能文档、组件/插件描述文件缺失、reload/unload未成对等常见 PR 结构问题。

CI 生产构建不要作为常规本地验证重复执行。PR 的 CI 工作流会依次运行:pnpm run typepnpm run lint-checkpnpm run build-core→ 在registry/安装依赖 →pnpm run build-features。仅在显式要求复现 CI 失败、改动共享构建基础设施或准备发布时,才在本地执行这些生产构建。

当改动影响页面行为时,还需打开浏览器控制台检查新增运行时错误,并在受影响的页面类型(视频、番剧、直播、动态、空间、设置面板等)上实测。

分支与提交约定

AGENTS.md 的 Branches And Commits 章节是提交前必须遵守的约定:

  • 新功能preview-features为基线分支。
  • Bug 修复preview-fixes为基线分支。
  • commit message只需清晰描述改动;仓库不强求严格的 conventional commit 格式(CONTRIBUTING.md 也明确中英文随意、不做 commitlint 强校验)。
  • 不要创建 release tag、推送发布分支或执行发布步骤,除非任务明确与发布相关。
  • 提交仅含源代码修改,不要把dist/registry/dist/产物、无关缓存、profile、本地调试或包管理器输出文件提交上去。

面向 Agent 的实操自检清单

综合 AGENTS.md 全部章节,一个编码 Agent 在本仓库完成任务时应按如下顺序自检:

  1. 已通读 CONTRIBUTING.md,并按需阅读 dev-tools/dev-server/README.md 理解协议细节。
  2. 正确判断改动落点:本体在src/,可安装组件在registry/lib/components/,扩展性插件在registry/lib/plugins/,第三方独立组件走 registry/lib/docs/third-party.ts。
  3. 组件/插件均以index.ts为 webpack 入口,用defineComponentMetadata/PluginMetadata定义,author齐全,命名具体清晰,index.md描述不重复。
  4. 生命周期正确:entry只做启动工作,页面匹配交给urlInclude/urlExclude,清理放unload,需要热开关时reload/unload成对。
  5. 样式进入 SCSS 并复用共享 mixin,设置控制 CSS 时用 html/body 上的 class 开关。
  6. 代码风格与类型契约符合仓库约定,不引入宽泛选择器与误导性命名。
  7. 验证按风险分级执行:pnpm run typepnpm run lint-check,必要时通过 dev-server 的build/watch/start-debug驱动功能编译,并在真实浏览器与对应页面类型中实测。
  8. 不手动改生成文件、不提交构建产物,分支基于preview-featurespreview-fixes,commit message 清晰描述改动。

【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询