Scalar 仓库 AI Agent 协作指南:从环境搭建到代码提交流程的完整解读
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
Scalar 是一个基于 Vue 3 + TypeScript 的 API 文档与测试工具开源 monorepo,同时产出@scalar/api-reference(OpenAPI 文档渲染)与@scalar/api-client(API 测试客户端)两大核心产品。本文以仓库根目录的 CLAUDE.md(即该仓库的 AI Agent 规范文档)为骨架,结合仓库内的真实配置与源码,系统解读 AI 编码 Agent(Cursor、Claude Code、GitHub Copilot 等)在 Scalar 代码库中高效工作的完整流程:从环境准备、构建与测试命令,到代码规范、PR 要求与可视化验证,帮助你在贡献或二次开发时快速对齐项目的工程约定。
项目概览:一个 40+ 包、16 集成的超大 monorepo
CLAUDE.md 开篇明确了 Scalar 的技术栈与规模:
- 前端:Vue 3、Composition API、TypeScript
- 样式:Tailwind CSS
- 测试:Vitest(单元测试)+ Playwright(E2E)
- Lint:ESLint(Vue 文件)+ Biome(TypeScript 文件)
- 包规模:40+ 个支持包(
packages/下 43 个包)与 16 个框架集成(Express、Fastify、Hono、NestJS、Next.js、Nuxt 等) - 工具链:pnpm workspaces 管理依赖、Turbo 编排构建、Vite 构建 Vue 包、
tsc构建纯 TypeScript 包
这些数字都能在仓库中直接验证:根 package.json 中声明了 pnpm 10.16.1 与turbo、vitest、biome、lefthook等全部工具链依赖;integrations/目录下确实存在 express、fastify、hono、nestjs、nextjs、nuxt、django-ninja、dotnet、rust 等 16+ 个集成目录。
环境准备:Node.js v24 与 pnpm 10.16.1+
Agent 进入仓库后的第一步是核对运行环境。仓库通过.nvmrc固定 Node 版本为v24(见 .nvmrc),而 package.json 的engines字段声明pnpm: ^10.16.1,packageManager字段为pnpm@10.16.1——也就是说 pnpm 版本由 corepack 自动激活,无需全局安装。
首次设置只需两条命令:
pnpm install pnpm build:packages其中build:packages是开发前必须执行的步骤,它会用 Turbo 过滤出packages/**下的所有包并全部构建(对应根 package.json 中的脚本turbo --filter "./packages/**" --concurrency=100% build)。因为所有 workspace 内部依赖都采用workspace:*协议,任何包被改动前都需要先确保其上游依赖已构建完成。
常用命令速查表
CLAUDE.md 将常用命令整理为一张表,结合根 package.json 的 scripts 定义,含义如下:
| 任务 | 命令 | 说明 |
|---|---|---|
| 构建所有包 | pnpm build:packages | Turbo 过滤./packages/**构建,首次开发前必跑 |
| 构建集成 | pnpm build:integrations | 构建./integrations/**下的框架集成 |
| 全量清理重装 | pnpm clean:build | pnpm clean && pnpm install && pnpm build:packages一条龙 |
| 单元测试 | pnpm test | 全仓测试(Turbo 过滤 packages/integrations/projects/tooling) |
| 单包单次测试 | pnpm vitest packages/helpers --run | 从根目录按路径过滤,跑完即退 |
| 单包 watch 测试 | pnpm vitest packages/api-client | 开发时持续监听 |
| 按名称过滤测试 | pnpm test your-test-name | 匹配测试名 |
| Lint 检查 | pnpm lint:check | biome lint --diagnostic-level=error,主 lint 命令 |
| Lint 修复 | pnpm lint:fix | Biome 写回 + ESLint 修复 Vue 文件 |
| 格式化 | pnpm format | Prettier 写回 + Biome format 写回 |
| 类型检查 | pnpm types:check | Turbo 编排全仓types:check |
一个关键提示是:根目录没有统一的pnpm dev,开发服务器必须按包启动:
pnpm --filter @scalar/api-reference dev pnpm --filter @scalar/api-client dev pnpm --filter @scalar/components dev各开发服务器的用途对比如下:
| 包 | 用途 |
|---|---|
api-reference | 主 API 文档渲染 playground(端口 5173) |
api-client | API 测试客户端 playground(Vite 自动分配端口) |
components | Storybook 组件库(端口 5100) |
void-server | HTTP 镜像服务器(端口 5052),供测试使用 |
架构:Workspace 布局与双构建策略
目录结构
packages/ # 核心包(@scalar/*),43 个 npm 包 integrations/ # 框架集成(Express、FastAPI 等) examples/ # 各种框架的使用示例 projects/ # 可部署应用(scalar-app、proxy-scalar-com、galaxy-scalar-com) tooling/ # 内部脚本与 changelog 生成器projects/scalar-app同时构建 Electron 桌面应用和 client.scalar.com(仓库内可见其 72 个.vue与 267 个.ts文件)tooling/存放构建辅助脚本,其中 vite-lib-config.ts 是所有 Vue 包的共享 Vite 库构建配置
构建系统:标准工具直用,无自定义 CLI
Scalar 刻意不写自定义构建 CLI,只用两种标准策略:
tsc+tsc-alias:用于纯 TypeScript 包(helpers、types、openapi-parser、各集成),每个包使用自己的tsconfig.build.json,用tsc-alias处理路径别名。vite build:用于 Vue 组件包(components、api-reference、api-client),基于 Vite 8 + Rolldown,构建时抽取 CSS、保留模块结构。
两条策略都外部化依赖(库产物不打包第三方依赖)。api-reference是特例:它有默认构建与 standalone 构建两种,standalone 构建(vite.standalone.config.ts)会把一切打包进单一产物,用于 CDN 场景——这与 vite.standalone.config.ts 的存在相互印证。类型检查则按包类型区分:纯 TS 用tsc --noEmit,Vue 包用vue-tsc --noEmit。
从 turbo.json 可以看到任务依赖编排:build依赖上游^build,types:check依赖build,test依赖^build且关闭缓存——这正是"改包先建上游"机制的来源。
关键包关系
@scalar/core:共享渲染逻辑,被api-reference和各集成消费(见 packages/core)@scalar/themes:CSS 变量与设计 token,供所有 UI 包使用@scalar/components:Vue 组件库(带 Storybook)@scalar/oas-utils:OpenAPI 工具,api-reference与api-client共用@scalar/types:共享 TypeScript 类型,必须从具体入口导入(如@scalar/types/api-reference),不能从根导入——这一约束在 biome.json 的noRestrictedImports规则中被强制为 error 级别
依赖版本管理
内部依赖一律使用workspace:*;共享的第三方版本统一定义在 pnpm-workspace.yaml 的catalogs:下(如vue: ^3.5.40、vite: 8.1.5、vitest: 4.1.10),各包的package.json里用catalog:*引用。这样可以把全仓数十个包共用的依赖版本收敛到一处,避免版本漂移。
工具分工
- Biome:
.ts文件的 lint 与格式化(配置见 biome.json) - ESLint:
.vue文件的 lint - Prettier:
.vue、.md、.json、.css、.html、.yml的格式化 - Lefthook:pre-commit 钩子,对暂存文件运行 Prettier + Biome(配置见 lefthook.yml,还包含 schemas 类型生成与 release-notes schema 生成等自动任务)
代码规范:先复用,再编写
优先复用@scalar/helpers
CLAUDE.md 明确要求:写新工具函数之前,先查@scalar/helpers(源码位于 packages/helpers/src)。该包按类别覆盖了几乎全部常见需求:
| 类别 | 覆盖内容 |
|---|---|
array/object | 数组操作、深比较、key 助手、路径访问、localStorage |
dom/node | DOM 助手、Node 专属路径助手 |
errors/file/formatters | 错误处理、文件工具、值格式化 |
general/string | 通用工具、capitalize/hash/truncate/camel-to-title |
http | HTTP 方法、头部、状态码、MIME 类型 |
json/markdown/regex | JSON Pointer、标题提取、变量查找替换 |
queue/url | 异步队列、URL 校验合并与代理助手 |
playwright/storybook/testing/theme/types | 测试/主题/类型工具 |
只有确实没有现成实现时,才允许新增 helper。
TypeScript 与 Vue 规范要点
TypeScript 侧的关键约定:
- 优先
type而非interface - 函数必须有显式返回类型
- 避免
any,类型不明用unknown - 避免 enum,用字符串字面量联合类型
- 能
const就不let - 类型导入用
import type { Foo } - 单引号、尾逗号、尽量省略分号
Vue 侧约定:
- 一律 Composition API +
<script setup lang="ts"> - 样式用 Tailwind utility class
- Props 解构带默认值:
const { prop1, prop2 = 'default' } = defineProps<Props>() defineProps/defineEmits必须显式类型<script setup>推荐顺序:imports → props/emits → state/computed/methods → 生命周期
注释与文档
- 注释解释why而不是 what
- 使用友好、人性化的语气,避免缩略写法(写 "do not" 而非 "don't")
- 导出的类型与函数要加 JSDoc
- 临时方案用 TODO 注释标记
测试规范:范围优先,跑包不跑仓
Scalar 的测试体系分三层:单元测试(Vitest,*.test.ts紧邻源码)、E2E(Playwright,位于packages/api-reference与packages/components)、集成测试(pnpm vitest integrations/*)。
最重要的一条纪律是:永远把测试范围限定在改动包内。不要在仓库根目录直接跑pnpm test(它会触发整个 monorepo 的测试套件,慢且噪音大)。推荐两种方式:
# 方式一:从根目录用路径过滤(单次运行,推荐) pnpm vitest packages/helpers --run pnpm vitest packages/oas-utils --run pnpm vitest integrations/fastify --run # 方式二:进入包目录 cd packages/helpers && pnpm test --run # watch 模式(开发中) pnpm vitest packages/api-client # 从根目录仅当有意验证全仓(例如合入前的最终 sanity check)时才用根pnpm test。
测试编写标准也很明确:
- 从
vitest显式导入describe/it/expect(不用全局变量) - 测试文件命名为
name.test.ts,与源码同目录 - 顶层
describe()与文件名一致 - 测试描述不以 "should" 开头(写
it('generates a slug'),不写it('should generate a slug')) - 尽量少 mock,偏好纯函数
- Vue 组件测试验证行为,不验证 DOM 结构或 Tailwind class 细节
需要记住的 Biome 规则
在 biome.json 中同样能查到这些规则的实际配置:
noBarrelFile: error—— 禁止 barrel 文件(index.ts入口除外)noReExportAll: warn—— 避免export * from(在api-reference与openapi-parser中升级为 error)noTsIgnore: error—— 禁止@ts-ignore(必要时用带说明的@ts-expect-error)useAwait: error—— 异步函数必须使用awaitnoExportsInTest: error—— 测试文件不允许 exportnoFloatingPromises: warn—— 所有 Promise 必须被处理
此外,biome.json 中还有一条值得注意的noRestrictedImports规则:源码文件禁止导入@test/*与**/test/**(测试助手不得进源码),且@scalar/components必须从子路径导入(如@scalar/components/button)而不是包级 barrel。
Git 工作流与 PR 要求
分支命名
claude/feature-description—— 新功能claude/fix-description—— Bug 修复claude/chore-description—— 维护性改动
Commit Message
使用 conventional commits 格式,现在时态("add" 而非 "added"),尽量带 scope:
feat(api-client): add new endpoint语义化 PR 标题
PR 标题必须遵循type(scope): subject:
fix(api-client): crashes when API returns null ^ ^ ^ | | subject | package scope type (feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert)Ticket 与 Issue 关联
当提示词或相关线程中提供了Linear ticket ID(如DOC-5102、ENG-123)或GitHub issue 号时,必须在 PR 中关联,方便项目管理集成自动追踪进度。
Linear 的 magic words 分两类:关闭类(close/closes/closed/fix/fixes/fixed/resolve/resolves/resolved)与非关闭类(ref/refs/references/part of/related to/contributes to/toward/towards),且必须放在 PR 描述中(不是评论里):
Fixes DOC-5102 Part of ENG-123 Resolves DOC-5102, ENG-456GitHub issue 则支持跨仓库语法与多 issue 关联:
| 场景 | 语法 | 示例 |
|---|---|---|
| 同仓库 | KEYWORD #ISSUE | Closes #42 |
| 不同仓库 | KEYWORD OWNER/REPO#ISSUE | Fixes scalar/scalar#100 |
| 多个 issue | 重复完整语法 | Resolves #10, resolves #42 |
推荐在 PR 描述底部加## Ticket小节统一放置。若 Linear 与 GitHub issue 同时存在,两者都加。
Changesets
凡涉及packages/*、integrations/*、projects/*的代码变更,都需要添加 changeset,且只用patch或minor(禁用major)。开 PR 前先检查状态:
pnpm changeset status # 检查是否需要版本变更 pnpm changeset # 添加 changeset改代码后的自查清单
CLAUDE.md 要求任何代码变更后,只针对你改动的文件和包运行 lint、format 与类型检查,绝不在全仓跑:
# 1. 只对改动文件做 lint + format CHANGED=$(git diff --name-only HEAD) pnpm biome check --write --diagnostic-level=error --no-errors-on-unmatched --files-ignore-unknown=true $CHANGED pnpm prettier --write $CHANGED # 2. 只跑受影响包的测试 pnpm vitest packages/<package-name> --run pnpm vitest integrations/<integration-name> --run # 3. 只对受影响包做类型检查 pnpm --filter @scalar/<package-name> types:check # 4. 开 PR 前检测未使用的导出、文件与依赖 pnpm knip所有检查必须干净通过——不允许带着 lint 错误、类型错误或未使用导出提交代码。
可视化测试:改动 UI 必须附截图/视频
由于大多数包的上游依赖最终都会汇入api-reference、api-client、components三大可视化表面,因此任何 UI 改动都必须附带视觉产物(截图或演示视频)。
准备工作
pnpm install pnpm build:packages或者在包目录里用pnpm turbo dev/pnpm turbo build自动构建上游依赖。
三个 playground 的启动方式
| 包 | 快速启动 | Turbo 方式 |
|---|---|---|
api-reference | cd packages/api-reference && pnpm dev | pnpm turbo --filter @scalar/api-reference dev |
api-client | cd packages/api-client && pnpm dev | pnpm turbo --filter @scalar/api-client dev |
components | cd packages/components && pnpm dev | pnpm turbo --filter @scalar/components dev |
各包的详细说明可参见 packages/api-reference/AGENTS.md 与 packages/api-client/AGENTS.md。其中api-client有web / app / modal三种布局:web 是独立浏览器客户端(单请求聚焦,也是默认 dev 目标);app 是完整桌面风格布局(含侧边栏、集合、环境与 workspace 管理);modal 是浮层布局,也可通过 api-reference playground 中任意操作的 "Test Request" 按钮触发。
如何选择 playground
| 改动区域 | 首选 playground | 次选 |
|---|---|---|
| 基础组件(按钮、输入框、弹窗) | componentsStorybook | api-reference、api-client |
| 主题、CSS 变量、设计 token | api-reference | api-client、components |
| 侧边栏、搜索、OpenAPI 渲染 | api-reference | api-client |
| 请求编辑器、响应查看器、认证 | api-client(web + app) | api-reference(modal) |
| 代码高亮、代码片段 | api-reference | api-client |
| 图标 | componentsStorybook | api-reference |
PR 中嵌入视觉产物
产物保存在/opt/cursor/artifacts/,用描述性的 snake_case 命名,并在 PR 描述中通过绝对路径引用:
<img src="/opt/cursor/artifacts/screenshot_before.png" alt="Before change" /> <img src="/opt/cursor/artifacts/screenshot_after.png" alt="After change" /> <video src="/opt/cursor/artifacts/demo_feature.mp4" controls></video>PR 描述中建议加## Visual小节统一放置产物。捕获要点:改动 UI 的前后对比截图、新功能的上下文截图、来自最相关 playground 的产物、交互行为的演示视频;若改动横跨多个可视化表面,则从多个 playground 各取产物。
OpenAPI 术语统一
为了让所有贡献者和 Agent 使用一致的术语,仓库规定:
- OpenAPI(而非 "Swagger")—— 规范格式本身
- API description(而非 "API spec" 或 "API definition")—— 元数据文档
- Schema—— 请求/响应形状的数据模型
- Dereference—— 用值替换所有
$ref - Bundle—— 把外部
$ref的值拉进单个文件 - Resolve—— 在
$ref处查找值而不修改文档
这套术语贯穿packages/openapi-parser、packages/openapi-validator等包的文档与代码,写作和讨论时保持一致有助于避免歧义。
开发环境注意事项(Cursor Cloud 场景)
针对云端 Agent 环境,CLAUDE.md 补充了几条实用提示:
- Node.js v24 由 nvm 管理,pnpm v10.16.1 由 corepack 激活,无需全局安装
pnpm install后可能看到 esbuild 构建脚本被忽略的警告——可安全忽略:Vite 8 使用 Rolldown,不需要 esbuild 的平台二进制也能完成构建pnpm --filter @scalar/api-reference dev固定监听5173端口- 部分包(如
openapi-parser、snippetz)存在与@/路径别名解析相关的既有测试失败,属于环境已知问题而非新引入 - 依赖网络服务的测试必须先启动测试服务器:
pnpm script run test-servers # 启动 void-server(5052) 与 proxy(5051) pnpm script wait -p 5051 5052 # 等待端口就绪- 快速验证测试框架可用性:
pnpm vitest packages/oas-utils --run
延伸阅读
想进一步了解贡献流程,可阅读 CONTRIBUTING.md,其中涵盖了 PR 要求、changesets 与自动生成文件(如各集成的 README.md 由pnpm script generate-readme生成、Java/.NET 的枚举由 TypeScript 客户端配置生成)。更多仓库背景与产品能力可参见根 README.md。
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考