Gemini CLI 贡献指南:从 CLA 到 preflight 全流程,构建、测试与沙箱开发环境实战
【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli
本文以 Gemini CLI 仓库的 CONTRIBUTING.md 为主体,系统讲解向该项目贡献代码与文档的完整流程:签署 CLA、寻找可认领的 Issue、遵循 Pull Request 规范,并深入拆解开发环境的搭建方式——包括npm run build构建流程、npm run preflight质量门禁背后的每一步检查、review.sh自动评审工具、VS Code 调试与 React DevTools 调试,以及 macOS Seatbelt 与容器化沙箱两套隔离方案的配置细节。读完本文,你可以独立完成一次从克隆仓库到提交 PR 的完整贡献,并理解项目各条 npm 脚本命令的真实实现。
贡献前的两项准备
签署 Contributor License Agreement
任何贡献都必须附带 Google 的 CLA(Contributor License Agreement)。作者(或其雇主)保留对贡献的版权,CLA 只是授予项目使用和再分发贡献的许可。如果你或你当前的雇主已经签署过 Google CLA(哪怕是针对其他项目的),通常无需重复签署。你可以在 Google CLA 页面(cla.developers.google.com)查看当前协议状态或签署新的协议。
遵守社区行为准则
项目遵循 Google 开源社区行为准则(Google Open Source Community Guidelines),所有 issue 讨论、PR 评审都应在此框架内进行。
代码贡献流程
五步贡献流程
- 找一个 Issue:被标记为
🔒Maintainers only的 Issue 仅保留给项目维护者,不会接受相关 PR。对于认为适合社区贡献的 Issue,可以在 Issue 下留言,由维护者评估后打上help-wanted标签(只有维护者可以添加该标签)。 - Fork 仓库并创建新分支。
- 在
packages/目录中完成修改:所有产品代码都位于 packages/ 下的多个工作区包中(cli、core、sdk、devtools、a2a-server、vscode-ide-companion、test-utils等),这一点可以从 package.json 中的"workspaces": ["packages/*"]得到印证。 - 确保所有检查通过:运行
npm run preflight。 - 提交 Pull Request。
自动评审工具
项目提供了自动评审工具,帮助检测常见反模式、测试缺失等容易遗漏的问题。所有提交(包括项目成员自己)都必须经过 PR 评审,自动评审用于辅助而非替代人工评审。有两种运行方式:
方式一:使用辅助脚本(推荐)
./scripts/review.sh <PR_NUMBER> [model]该脚本会自动完成:把 PR checkout 到独立 worktree、安装依赖、构建项目、启动评审工具。从 scripts/review.sh 的源码可以看到,脚本要求预先在~/git/review/gemini-cli目录有一份仓库克隆,会先用gh pr view校验 PR 是否存在,然后打开 PR 页面供人工核对。脚本有两点重要提醒:
- 警告:运行
review.sh前,必须人工确认被评审 PR 的代码可以安全执行、不包含数据外泄攻击。 - 强烈建议 PR 作者在自己 PR 创建后立即运行此脚本,在维护者完整评审前先本地发现并修复简单问题。
模型选择:脚本默认使用最新的 Pro 模型(gemini-3.1-pro-preview,这一点在 scripts/review.sh 中可见model="${2:-gemini-3.1-pro-preview}")。如果 Pro 配额不足,可以用 Flash 模型运行:
./scripts/review.sh <PR_NUMBER> gemini-3-flash-preview方式二:在 Gemini CLI 中手动运行
如果 PR 代码已经在本地 checkout 并构建完成,可以直接在 CLI 提示符中执行:
/review-frontend <PR_NUMBER>Issue 的自我认领与取消认领
- 在 Issue 下评论
/assign即可认领;评论/unassign取消认领。评论内容必须只有这一行文字,不能包含其他内容。 - 同时最多只能认领 3 个 Issue;只有打了
help wanted标签的 Issue 才允许自我认领;Issue 必须处于未认领状态才能被认领。
Pull Request 六项规范
不满足这些标准的 PR 可能会被直接关闭。
1. 必须关联已有 Issue所有 PR 都要关联 Issue 跟踪系统中的一个已有 Issue,确保每个变更在写代码前已被讨论并与项目目标对齐:Bug 修复关联对应的 bug 报告;新功能关联经维护者批准的提案 Issue。如果不存在对应 Issue,PR 会被自动关闭并附上提醒评论。正确的工作流是先开 Issue 等待反馈,再开始编码。
2. 保持小而聚焦偏好小颗粒、原子的 PR,一个 PR 只解决一个 Issue 或添加一个自包含的功能。不要在一个 PR 里混入 Bug 修复、新功能和重构。大改动应拆成一系列可以独立评审、独立合并的小 PR。
3. 用 Draft PR 获取早期反馈尚未完工的工作请使用 GitHub 的 Draft Pull Request 功能,向维护者表明 PR 还未进入正式评审、仅开放讨论。
4. 确保所有检查通过提交前运行npm run preflight,它会执行全部测试、lint 和其他风格检查(下节详解)。
5. 更新文档如果 PR 引入了面向用户的变更(新命令、修改的 flag、行为变化),必须同步更新/docs目录下的相关文档。
6. 写清晰的 commit message 和 PR 描述commit message 遵循 Conventional Commits 标准。示例:
- 好的 PR 标题:
feat(cli): Add --json flag to 'config get' command - 坏的 PR 标题:
Made some changes
PR 描述中要解释变更的"为什么",并链接相关 Issue(如Fixes #123)。
Fork 后的 CI 配置
Fork 仓库后可以运行 Build、Test 和 Integration test 工作流,但要让集成测试跑起来,需要在自己的 fork 中添加名为GEMINI_API_KEY的 GitHub Repository Secret,值设为一个有效的 API key。该密钥仅对你的仓库私有。此外,还需到仓库的Actions标签页手动启用工作流(页面中央的大蓝色按钮)。
开发环境搭建与工作流
前置条件
- Node.js:
- 开发环境请使用 Node.js
~20.19.0,因为上游开发依赖的兼容性问题需要锁定该版本(可用 nvm 管理); - 生产环境运行 CLI 则任意
>=20的版本都可以。package.json 中声明的"engines": { "node": ">=20.0.0" }正对应这一生产要求。
- 开发环境请使用 Node.js
- Git。
克隆与构建
git clone https://github.com/google-gemini/gemini-cli.git # 或你的 fork 地址 cd gemini-cli安装依赖(包括 package.json 中定义的工作区依赖与根依赖):
npm install构建整个项目(所有包):
npm run build该命令通常会把 TypeScript 编译为 JavaScript、打包资源并准备各包的可执行产物。在 package.json 中可以看到"build": "node scripts/build.js",对应实现是 scripts/build.js,构建细节可参考它和package.json的 scripts 字段。
启用沙箱构建
CONTRIBUTING.md 强烈建议开发者启用沙箱(Sandbox),最低要求是在~/.env中设置GEMINI_SANDBOX=true并确保有可用的沙箱提供方(macOS Seatbelt、docker 或 podman)。要同时构建geminiCLI 和沙箱容器,在仓库根目录运行:
npm run build:all如果想跳过沙箱容器的构建,用npm run build即可。从 package.json 可确认build:all的完整语义:
"build:all": "npm run build && npm run build:sandbox && npm run build:vscode", "build:sandbox": "node scripts/build_sandbox.js",即依次执行主构建、沙箱镜像构建(scripts/build_sandbox.js)以及 VS Code 伴侣扩展构建。
运行 CLI
构建后从源码启动 Gemini CLI:
npm start对应实现为cross-env NODE_ENV=development node scripts/start.js(见 scripts/start.js)。如果想在 gemini-cli 目录之外运行源码构建,可以:
npm link path/to/gemini-cli/packages/cli # 或者 alias gemini="node path/to/gemini-cli/packages/cli"运行测试
项目包含两类测试:单元测试与集成测试。
单元测试
npm run test覆盖packages/core与packages/cli的测试套件。从 package.json 可以看到它实际上是"test": "npm run test --workspaces --if-present && npm run test:sea-launch",即在所有工作区运行各自存在的测试,外加 sea/sea-launch.test.js;并且还有"posttest": "npm run build"钩子。提交任何变更前都应确保测试通过,更彻底的检查是npm run preflight。
集成测试
集成测试用于验证端到端功能,不包含在默认的npm run test中:
npm run test:e2epackage.json 显示其定义为cross-env VERBOSE=true KEEP_OUTPUT=true npm run test:integration:sandbox:none,即不带沙箱(GEMINI_SANDBOX=false)地运行 integration-tests/ 目录下的 vitest 套件。仓库还提供了test:integration:sandbox:docker、test:integration:sandbox:podman等变体。集成测试框架的详细说明见 docs/integration-tests.md——该文档指出,运行集成测试前需要先执行npm run bundle生成被测试的 release bundle,且每次修改 CLI 源码后都要重新 bundle。
Lint 与 preflight 检查
npm run preflight是提交前的总闸门。对照 package.json 的定义:
"preflight": "npm run clean && npm ci && npm run format && npm run build && npm run lint:ci && npm run typecheck && npm run test:ci"即依次执行:清理(scripts/clean.js)、npm ci全新安装、Prettier 格式化、全量构建、CI 模式 lint(scripts/lint.js 的lint:all)、TypeScript 类型检查(各工作区 typecheck 加上 evals / integration-tests / memory-tests 的tsc -b),以及test:ci(各工作区 CI 测试 + 脚本测试 + SEA 启动测试)。
ProTip:克隆后创建 git pre-commit 钩子,保证每次提交都是干净的:
echo " # Run npm build and check for errors if ! npm run preflight; then echo \"npm build failed. Commit aborted.\" exit 1 fi " > .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit也可以单独执行:
- 格式化:
npm run format(Prettier 按项目风格格式化全部文件,含 Markdown); - Lint:
npm run lint(ESLint,--max-warnings 0零警告策略); - 自动修复:
npm run lint:fix。
另外 package.json 还配置了husky+lint-staged的提交时检查:暂存的*.{js,jsx,ts,tsx}会被 Prettier 格式化并经 ESLint--fix修正,*.{json,md}会被 Prettier 格式化。
编码规范
- 遵循现有代码库的风格、模式和约定;
- 阅读 GEMINI.md(项目根目录),其中包含 AI 辅助开发的具体约定,包括 React、注释和 Git 使用规范;
- 特别注意导入路径:项目用 ESLint 强制限制跨包的相对导入(eslint.config.js),应使用包名而非跨包相对路径。
调试
VS Code:在根目录运行
npm run debug该命令是cross-env DEBUG=1 node --inspect-brk scripts/start.js,会暂停执行直到调试器附着,此时可以用 Chrome 打开chrome://inspect连接调试器。也可以直接使用 .vscode/launch.json 中的 "Attach" 启动配置,或者 "Launch Program" 配置直接启动当前打开的文件,但一般推荐用 F5 对应的主配置("Build & Launch CLI" 会先执行npm run build-and-start,并在env中默认关闭GEMINI_SANDBOX以便断点生效)。
要在沙箱容器内命中断点,运行:
DEBUG=1 gemini注意:如果项目的.env文件里有DEBUG=true,由于自动排除机制,它不会影响 gemini-cli;给 gemini-cli 专用的调试设置请写入.gemini/.env。
React DevTools:CLI 的界面基于 React(Ink)构建,可以用 React DevTools 调试:
以开发模式启动 CLI:
DEV=true npm start安装并运行与 CLI 的
react-devtools-core版本(6.x,见 package.json 中react-devtools-core: 6.1.2)匹配的 React DevTools 6:npm install -g react-devtools@6 react-devtools # 或者 npx react-devtools@6运行中的 CLI 会自动连接 React DevTools:
沙箱机制详解
macOS Seatbelt
在 macOS 上,gemini使用 Seatbelt(sandbox-exec)加载permissive-open策略(packages/cli/src/utils/sandbox-macos-permissive-open.sb)。从该策略文件源码看,它以(deny default)拒绝默认操作,显式允许从宿主机任意位置读文件((allow file-read*))、进程 exec/fork(子进程继承策略从而保持被沙箱化)、向自身发信号(如写关闭管道时的 SIGPIPE)以及读取有限的 sysctl 信息,写入则被限制在项目文件夹内,同时默认放行广泛的文件读取与出站网络("open")。
可以通过设置SEATBELT_PROFILE=strict-open(写入环境或.env)切换到strict-open策略(packages/cli/src/utils/sandbox-macos-strict-open.sb),它把读取和写入都限制在工作目录内,但默认仍放行出站网络。内置的全部策略档位为permissive-{open,proxied}、restrictive-{open,proxied}、strict-{open,proxied}(对应 packages/cli/src/utils/ 下的六个.sb文件)。也可以自定义策略:设置SEATBELT_PROFILE=<profile>并在项目设置目录.gemini下创建.gemini/sandbox-macos-<profile>.sb。
容器化沙箱(全平台)
在 macOS 或其他平台上想要更强的容器级隔离,可以在环境或.env中设置:
GEMINI_SANDBOX=true|docker|podman|<command>指定的命令(true时为docker或podman之一)必须已安装在宿主机上。启用后,npm run build:all会构建一个最小的沙箱容器镜像,npm start会启动该镜像的一个全新实例;首次构建约需 20–30 秒(主要是拉取基础镜像),之后构建和启动的开销都很小。默认构建(npm run build)不会重建沙箱镜像。
容器沙箱会以读写方式挂载项目目录(以及系统临时目录),并随 Gemini CLI 的启动/停止自动启动/停止/移除。沙箱内创建的文件会自动映射到宿主机的用户/组。通过SANDBOX_{MOUNTS,PORTS,ENV}可以额外指定挂载、端口和环境变量。还可以为项目完全定制沙箱:在.gemini下创建.gemini/sandbox.Dockerfile和/或.gemini/sandbox.bashrc,然后以BUILD_SANDBOX=1运行gemini触发定制沙箱的构建。
代理网络(Proxied networking)
所有沙箱方式(包括使用*-proxied策略的 macOS Seatbelt)都支持通过自定义代理服务器限制出站网络流量,用GEMINI_SANDBOX_PROXY_COMMAND=<command>指定。<command>必须启动一个监听:::8877的代理服务器。仓库提供了最小示例:docs/examples/proxy-script.md 中的代理只放行到example.com:443的 HTTPS 连接(例如curl https://example.com),拒绝所有其他请求。代理会随沙箱自动启动和停止。
手动发布
项目会为每个提交向内部 registry 发布产物。如果确实需要手动切一个本地构建:
npm run clean npm install npm run auth npm run prerelease:dev npm publish --workspaces其中npm run auth在 package.json 中定义为npm run auth:npm && npm run auth:docker,即依次执行npx google-artifactregistry-auth和gcloud auth configure-docker us-west1-docker.pkg.dev,分别完成 Artifact Registry 与 Docker 的发布认证。
文档贡献流程
项目要求文档与代码贡献保持同步,追求清晰、准确、完整,并尽量提供实用示例。
文档贡献五步
Fork 仓库并创建新分支;
在
/docs目录中完成修改;本地预览 Markdown 渲染效果;
Lint 并格式化改动——preflight 检查已包含对文档文件的检查:
npm run preflight提交 Pull Request。
文档组织结构
文档以 docs/sidebar.json 作为目录(table of contents)。从该文件源码可以看到,每个条目由label(显示名)和slug(对应文档路径,如docs/get-started/installation)构成,并按 "Get started"、"Use Gemini CLI" 等分组嵌套。新增文档时:
- 把 Markdown 文件创建在
/docs下的合适目录中; - 在
sidebar.json的相应分组中添加条目; - 确保所有内部链接使用相对路径且指向真实存在的文件。
写作风格
项目遵循 Google Developer Documentation Style Guide。关键要点:
- 标题使用 sentence case(句首大写);
- 用第二人称("you")称呼读者;
- 使用现在时;
- 段落短小、聚焦;
- 代码块使用正确的语言标签以启用语法高亮;
- 尽可能附上实用示例。
文档 Lint 与格式化
项目用 Prettier 保持文档风格一致,npm run preflight会检查 lint 问题。也可以单独运行:
npm run lint—— 检查 lint 问题;npm run format—— 自动格式化 Markdown 文件;npm run lint:fix—— 尽可能自动修复 lint 问题。
提交文档 PR 前请确保没有 lint 错误。
提交前自查清单
- 运行
npm run preflight确保所有检查通过; - 复查改动的清晰度与准确性;
- 确认所有链接可正确访问;
- 确保代码示例经过测试、确实可用;
- 如果尚未签署,请签署 CLA。
如果文档贡献过程中遇到问题:可以查看现有文档找范例、在仓库 Issue 中先讨论拟议的改动、或直接联系维护者。项目欢迎每一份让文档变得更好的贡献。
【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考