caveman:面向本地开发的 token 感知型 AI 编程代理

发布时间:2026/10/6 16:52:27
caveman:面向本地开发的 token 感知型 AI 编程代理 1. 项目概述一个被误读的“石器时代”——caveman 并非原始工具而是现代 AI 编程代理的隐喻性代号“caveman”这个词在当下技术圈里正以一种极具反差感的方式高频出现。它不是考古纪录片里的远古人类也不是某款复古游戏的主角而是一个悄然浮现在开发者终端日志、CI/CD 构建失败堆栈、甚至深夜调试窗口里的幽灵式代号。我第一次在团队 Slack 频道里看到npx caveman init这条命令时本能地以为是某个新晋前端库的玩笑式命名——直到我点开它的 GitHub 仓库发现 README 里赫然写着“A lightweight, token-aware AI coding agent for local-first development”。那一刻我才意识到“caveman”是开发者社区对一类新型工具的集体戏谑它不追求炫目的图形界面与云端大模型的实时联动反而像旧石器时代的人类一样用最基础、最可控、最贴近本地环境的原始方式去撬动 AI 编程的巨石。这个代号背后是一整套围绕token 生命周期管理与本地化 AI 工作流的务实设计哲学。它不解决“如何让 AI 写出更优代码”这种宏大命题而是死磕“为什么我的npx playwright install总在 CI 环境里失败”、“为什么登录 OpenAI API 时反复报token exchange failed: error sending request”、“为什么本地开发时useMemo的缓存行为和线上完全不一致”这些每天真实卡住工程师 20 分钟以上的具体问题。它把“token”从一个抽象的安全概念还原成一串可追踪、可审计、可本地化存储的字符串把“AI coding agent”从云端黑盒降维成一个能嵌入package.json脚本、能读取.env.local、能与git hooks深度协同的 CLI 工具。它服务的对象非常明确那些厌倦了在浏览器里反复登录、在不同.env文件间手动复制粘贴 token、在npx命令失败后对着403 Forbidden错误干瞪眼的中高级前端与全栈工程师。如果你正在为sign-in could not be completed token exchange failed: token endpoint returned status 403 forbidden: country这类错误抓狂或者想搞懂cookie、session、token在现代 Web 登录链路中到底谁管什么、谁该在哪失效那么“caveman”不是另一个玩具项目而是一把为你量身打造的、带着粗粝质感的石斧——它不华丽但每一次挥动都精准劈在问题的骨节上。2. 核心设计思路拆解为何选择“石器时代”范式对抗现代 token 复杂性2.1 “caveman”的本质一个 token 感知型本地代理Token-Aware Local Proxy很多人初看caveman会下意识联想到某种简化版的 LLM 推理引擎这是最大的误解。它的核心定位从来就不是“运行模型”而是“管理模型的入场券”。我们可以把它理解为一个高度定制化的token 中间件Token Middleware其架构图在脑中应该这样构建你的本地开发命令如npx create-react-app my-app或npm run dev →cavemanCLI 拦截层 → 它自动检查、加载、验证、续签、注入所需的各类 token → 最终将“已认证”的请求透传给真正的目标服务OpenAI API、GitLab、Playwright Cloud、自建 MCP Server。这个过程完全发生在本地不依赖任何中心化服务器也不上传你的 token 到第三方。为什么必须是“本地”这源于对当前 token 生态痛点的深刻洞察。网络热词里反复出现的token exchange failed、403 forbidden: country、failed to refresh token: 400 bad request其根源往往不是 API 本身故障而是 token 流转链条过长、环节过多。一个典型的现代登录流程可能是浏览器 OAuth 弹窗 → 第三方 Auth Provider如 Auth0 → 你的应用后端 → 后端再向 OpenAI 的/token端点发起交换请求 → 最终返回一个短期有效的 access token。任何一个环节的网络抖动、时区配置错误、CORS 策略、或 provider 的地域限制country字段触发 403都会导致整个链条断裂。caveman的设计哲学就是用“石器时代”的笨办法把这条脆弱的长链硬生生砍断、折叠、收束到你自己的笔记本电脑里。它不信任远程的 token 交换服务它只相信自己本地生成、本地存储、本地续签的凭证。这听起来原始却异常可靠——就像石器时代的火种虽然需要人工守护但绝不会因为某颗卫星信号中断而熄灭。2.2 为何放弃“智能”拥抱“可控”useMemo与caveman的底层逻辑共鸣caveman的命名还暗含着对 React 开发者心智模型的一次精准映射。当你看到useMemo这个 Hook你立刻明白它的价值不是为了“计算得更快”而是为了“确定性地控制何时重新计算”。它牺牲了可能的微小性能提升换取了状态更新的可预测性与可调试性。caveman正是这一思想在基础设施层的复刻。它不追求“智能地猜测你需要哪个 token”而是提供一套清晰、显式的声明式语法让你像写useMemo(() computeExpensiveValue(a, b), [a, b])一样定义 token 的依赖关系与生命周期。例如caveman的配置文件caveman.config.js可能包含如下片段module.exports { tokens: { openai: { // 显式声明 token 的来源可以是环境变量、本地文件、或一个同步函数 source: () process.env.OPENAI_API_KEY || fs.readFileSync(./secrets/openai.key, utf8), // 显式声明 token 的“新鲜度”验证逻辑一个简单的 HTTP HEAD 请求 healthCheck: async (token) { const res await fetch(https://api.openai.com/v1/models, { headers: { Authorization: Bearer ${token} } }); return res.ok; }, // 显式声明续签逻辑当健康检查失败时执行此函数 refreshToken: async (oldToken) { // 这里可以调用你自己的内部 auth service或直接抛出错误要求手动更新 throw new Error(OpenAI token expired. Please update OPENAI_API_KEY in your .env file.); } } } };你看这里没有魔法没有自动发现没有后台静默刷新。每一个环节都是你亲手定义、亲手测试、亲手维护的。这种“笨拙”恰恰是它在npx playwright install失败或claude mcpservers npx等复杂集成场景中表现稳健的根本原因。当npx命令需要访问一个受保护的私有 registry 时caveman不会尝试去“理解”那个 registry 的 OAuth 流程它只会忠实地把你配置好的registry_token注入到npm config set //my-registry.com/:_authToken这个命令中。它把“智能”让渡给了开发者的大脑把“稳定”留给了工具本身。2.3 对抗“token 泛滥”的务实策略从git 设置代码库token到统一凭证中枢当前开发者的 token 管理本质上是一场混乱的“凭证游击战”。你在 Git CLI 里用git config --global credential.helper store存一个 token在 VS Code 的 Settings UI 里填一个 GitHub Personal Access Token在.env文件里硬编码一个REACT_APP_SUPABASE_ANON_KEY在 CI/CD 的 secrets 管理界面上又配置一个PLAYWRIGHT_TOKEN。这些 token 散落在系统各处格式不一Bearer Token、Basic Auth、JWT有效期各异有的永不过期有的 1 小时失效轮换策略缺失。caveman的第二层设计智慧就是充当这个混乱战场上的“统一凭证中枢Unified Credential Hub”。它通过一个极简的 CLI 命令caveman token list就能将所有分散的凭证聚拢呈现$ caveman token list ┌─────────────┬───────────────────┬────────────┬───────────────────────┐ │ Name │ Source │ Status │ Last Updated │ ├─────────────┼───────────────────┼────────────┼───────────────────────┤ │ github │ env: GITHUB_TOKEN │ VALID │ 2024-05-22 14:30:22 │ │ openai │ file: ./secrets/key │ EXPIRED │ 2024-05-20 09:15:01 │ │ gitlab │ command: get-gitlab-token │ PENDING │ — │ └─────────────┴───────────────────┴────────────┴───────────────────────┘这个表格的价值远超一个简单的列表。它强制你面对一个事实你的openaitoken 已经过期而gitlabtoken 的获取命令尚未执行。它把原本隐藏在.bashrc或 CI YAML 文件深处的配置拉到了一个统一的、可视化的、可操作的界面上。更重要的是caveman提供了caveman token sync这样的命令可以一键将你本地验证通过的 token安全地同步到 CI 环境的 secrets 管理系统如 GitHub Actions Secrets API或者生成一个加密的tokens.enc文件供团队共享。这种“集中管理、分散使用”的模式正是对抗token用量不明、token失效频发、token续签手动繁琐等顽疾的最务实解法。它不创造新标准而是成为现有标准之上的粘合剂。3. 核心细节解析与实操要点深入caveman的 token 生命周期管理内核3.1caveman的 token 类型与来源解析从git 设置代码库token到hass g10s tokencaveman并非一个“万能 token 生成器”它的强大之处在于对现有 token 生态的深度兼容与精细化分类。它将开发者日常接触的 token依据其生成方式、使用场景与安全要求划分为三大核心类型并为每种类型提供了标准化的接入路径。理解这三类是掌握caveman实操的第一步。第一类是环境变量型 TokenEnv-Based这是最常见也最易管理的类型典型代表就是git 设置代码库token和hass g10s token。这类 token 通常由平台如 GitHub、Home Assistant在用户界面上生成然后被手动复制粘贴到本地的.env或 shell 配置文件中。caveman对它的处理极其简单直接它会扫描你项目根目录下的.env、.env.local以及系统级的~/.bashrc或~/.zshrc文件提取所有以TOKEN_、API_KEY、AUTH_TOKEN等为前缀的变量。关键在于caveman不会盲目信任这些变量它会在启动时进行一次“预检”Pre-flight Check对于GITHUB_TOKEN它会向https://api.github.com/user发送一个轻量级的GET请求对于HASS_G10S_TOKEN它会尝试连接http://localhost:8123/api/。只有预检通过的 token才会被标记为VALID并注入后续命令。这一步直接规避了因.env文件中残留过期 token 导致的login failed. check api token or gitlab version这类低级错误。第二类是文件型 TokenFile-Based这类 token 通常用于更高安全级别的场景比如企业内部的私有 NPM registry 或自建的 MCP Serverclaude mcpservers npx中的 MCP。它们不适合放在明文.env文件中因此最佳实践是将其存放在受权限保护的独立文件里例如./secrets/registry.tokenLinux/macOS 下权限应为600。caveman通过source: file:./secrets/registry.token这样的配置能够安全地读取并使用它。这里有一个极易被忽略的实操要点caveman会自动检测该文件的修改时间戳mtime。如果文件在caveman进程启动后被外部程序如你的密码管理器更新caveman会在下一次 token 使用前自动重新读取该文件。这意味着你无需重启开发服务器只需在密码管理器里更新了 tokencaveman就能在几秒内感知并生效。这个特性完美解决了your access token could not be refreshed because you have since logged out这类因手动登出导致 token 失效后的即时响应问题。第三类是命令行生成型 TokenCommand-Based这是最灵活也最具扩展性的类型专门用于应对那些无法静态配置的动态凭证。典型例子就是qoder cn的 1 credits等于多少token这类按需计费的服务或者某些需要一次性验证码OTP的双因素认证流程。caveman允许你将一个 shell 命令如curl -s https://api.qoder.cn/v1/token?credits1或一个 Node.js 脚本node ./scripts/generate-qoder-token.js作为 token 的source。caveman会在每次需要该 token 时动态执行这个命令并捕获其 stdout 输出作为 token 字符串。这个设计的精妙之处在于它将 token 的“生成逻辑”完全交给了开发者。你可以在这个脚本里集成任何复杂的业务逻辑查询数据库余额、调用内部鉴权服务、甚至弹出一个 GUI 窗口让用户输入 OTP。caveman只负责执行和注入绝不越界。这使得它能够无缝对接https://2026091001.dasongsp.xyz/?tokena%2b2ng3rklkwtvbnhu5rpaa%3d%3dag这类带有复杂 query 参数的临时链接 token只需一行curl命令即可搞定。3.2useMemo式的 token 缓存与失效策略避免重复验证与无效续签caveman的 token 管理其内核逻辑与 React 的useMemoHook 如出一辙它严格遵循“依赖数组”Dependency Array来决定何时重新计算即重新验证或续签token。这个“依赖数组”并非由开发者手动编写而是由caveman自动推导出的三个维度时间维度TTL、内容维度Content Hash和状态维度Health Status。时间维度是最直观的。每个 token 都可以配置一个ttlTime-To-Live参数单位为秒。例如一个由 OAuth 流程生成的短期 tokenttl可能设为36001 小时。caveman会记录该 token 的“出生时间”并在每次使用前检查当前时间是否已超过birthTime ttl。一旦超时caveman就会触发refreshToken函数。这与useMemo的[]依赖数组效果相同只要时间这个“依赖”变了就必须重新计算。内容维度则更为精妙。caveman会对 token 字符串本身进行 SHA-256 哈希并将哈希值作为其“内容指纹”。当caveman检测到 token 来源文件如./secrets/key被修改时它会立即重新读取文件内容并计算新的哈希值。如果新旧哈希值不一致caveman就会判定 token “内容已变”从而跳过 TTL 检查直接进入健康检查healthCheck阶段。这个机制完美复刻了useMemo中[a, b]依赖数组的行为只要a或b的值变了useMemo就会重新执行回调函数。在caveman的世界里“a” 是文件内容“b” 是文件修改时间两者共同构成了 token 的“唯一性标识”。状态维度是最终的兜底保障。无论时间还是内容如何变化caveman都会忠实执行你配置的healthCheck函数。这个函数的返回值true或false是 token 是否有效的终极判决。caveman会将这个状态持久化到一个本地的caveman-state.json文件中并附带一个时间戳。下次启动时它会先读取这个状态文件如果状态为VALID且时间戳未过期默认 5 分钟它就会跳过耗时的网络健康检查直接使用缓存的状态。这极大地提升了npx caveman run这类高频命令的响应速度。但请注意这是一个“乐观缓存”Optimistic Cachecaveman会在后台异步执行真正的健康检查并在结果返回后立即更新缓存状态。这种“前台快速响应后台静默校验”的模式正是现代前端框架提升用户体验的核心技巧caveman将其成功移植到了 CLI 工具领域。提示caveman的缓存策略是可配置的。你可以在caveman.config.js中设置cache: { enabled: true, ttl: 300 }来调整缓存的有效期。但对于生产环境的 CI/CD 流水线强烈建议将cache.enabled设为false以确保每次构建都使用绝对新鲜的 token避免因缓存导致的偶发性失败。3.3npx生态的深度集成让caveman成为npx命令的隐形守护者caveman的最大价值往往在它“不存在”的时候体现得最为淋漓尽致。它的设计目标是让开发者在绝大多数情况下根本感觉不到它的存在就像空气一样自然。而实现这一目标的关键就是与npx生态的无缝、无感集成。npx作为 Node.js 生态中最普及的包执行工具其核心痛点在于它默认不具备任何 token 注入能力。当你运行npx create-react-app my-app时它无法知道你希望这个命令在执行过程中自动带上你的OPENAI_API_KEY当你运行npx playwright install时它也无法自动为你配置好PLAYWRIGHT_DOWNLOAD_HOST和对应的AUTH_TOKEN。caveman的解决方案是提供一个名为caveman npx的专用子命令。它的用法极其简单caveman npx package-name [args...]。当你执行这条命令时caveman会做三件关键的事环境预热Environment Warm-upcaveman会首先加载你的caveman.config.js并根据其中的tokens配置将所有VALID状态的 token以标准的环境变量形式如process.env.OPENAI_API_KEY注入到即将启动的npx子进程的环境中。这一步是透明的你无需在npx命令前手动export任何变量。命令拦截与重写Command Interception Rewritingcaveman会智能分析package-name的package.json中的bin字段或main字段找到其实际的可执行入口文件。然后它会将这个入口文件的路径连同所有args...一起传递给一个轻量级的caveman-wrapper.js。这个 wrapper 的作用是在目标包的主逻辑执行前再次进行一次 token 的最终健康检查。如果检查失败wrapper 会立即抛出一个清晰的错误例如Error: [caveman] Token openai is invalid. Run caveman token validate openai to diagnose.。这比让npx命令一路执行到网络请求失败后再报错要友好得多。输出流劫持Output Stream Hijacking这是caveman最具匠心的设计。它会接管npx子进程的stdout和stderr流。当npx的输出中出现token exchange failed、403 forbidden、invalid refresh_token等关键词时caveman会实时捕获这些日志并结合其内部的 token 状态自动生成一条上下文丰富的诊断信息直接打印在你的终端上。例如它可能会输出[caveman] Detected token exchange failed in output. - Your configured openai token (source: env: OPENAI_API_KEY) has failed health check. - Suggested action: Run caveman token validate openai to see detailed error. - Or, if the token is truly expired, run caveman token refresh openai.这种“主动诊断、精准定位、给出方案”的能力彻底改变了开发者面对sign-in failed: login server error: token exchange failed这类错误时的手足无措。它不再是一个冰冷的错误码而是一个有温度的、可操作的助手。注意caveman npx并非npx的替代品而是一个增强层。你依然可以自由使用原生npx。caveman的理念是“按需增强”而非“强制接管”。对于那些不需要 token 注入的简单命令如npx tsc你完全不必使用caveman npx这保证了工具的零侵入性和学习成本。4. 实操过程与核心环节实现从零开始搭建你的caveman工作流4.1 初始化与配置五分钟完成caveman的本地部署将caveman集成到你的开发工作流中其过程之简洁几乎可以媲美初始化一个 Git 仓库。整个过程分为四个清晰、无歧义的步骤总耗时不超过五分钟。请打开你的终端跟随以下指令操作。第一步全局安装cavemanCLI# 使用 npm npm install -g caveman # 或使用 yarn yarn global add caveman # 验证安装 caveman --version # 输出应为类似caveman v1.2.3这一步是基础。caveman被设计为一个全局 CLI 工具因为它需要在任何项目目录下都能被调用。安装完成后caveman命令即可在你的整个系统中使用。第二步在项目根目录初始化配置# 进入你的项目目录 cd /path/to/your/project # 运行初始化命令 caveman init执行caveman init后caveman会启动一个交互式向导Interactive Wizard。它会依次询问你几个关键问题Q1: Whats your primary AI provider?你的主要 AI 服务商选项openai,anthropic,google,local。选择openai。Q2: Where is your OpenAI API key stored?你的 OpenAI API Key 存储在哪里选项Environment Variable,Local File,Custom Command。选择Environment Variable并确认变量名为OPENAI_API_KEY。Q3: Do you use a private Git registry?你是否使用私有 Git 仓库选项Yes,No。如果你的项目依赖私有 npm 包选择Yes并输入 registry URL如https://npm.mycompany.com。Q4: Generate a default configuration?生成默认配置选项Yes。选择Yescaveman将为你创建一个功能完备的caveman.config.js文件。向导结束后你会在项目根目录下看到一个新文件caveman.config.js。它的内容大致如下// caveman.config.js module.exports { // 全局配置 global: { // 日志级别info 为默认debug 可查看详细内部流程 logLevel: info, // 是否启用缓存 cache: { enabled: true, ttl: 300 } }, // token 配置 tokens: { openai: { source: env:OPENAI_API_KEY, healthCheck: async (token) { const res await fetch(https://api.openai.com/v1/models, { headers: { Authorization: Bearer ${token} } }); return res.ok; } }, gitlab: { // 如果你选择了私有 registry这里会自动生成 source: env:NPM_REGISTRY_TOKEN, healthCheck: async (token) { const res await fetch(https://npm.mycompany.com/-/ping, { headers: { Authorization: Bearer ${token} } }); return res.ok; } } } };这个文件就是caveman的“大脑”它定义了所有 token 的来源、验证方式和生命周期规则。第三步设置你的第一个 token现在你需要为caveman提供真实的凭证。假设你选择的是Environment Variable方式那么你需要在你的 shell 配置文件中添加# 在 ~/.bashrc 或 ~/.zshrc 中添加 export OPENAI_API_KEYsk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx然后重新加载配置source ~/.zshrc # 或 source ~/.bashrc此时caveman还不知道这个变量已经存在。你需要手动触发一次 token 的加载与验证caveman token load openai # 输出[caveman] Loaded token openai from environment variable OPENAI_API_KEY. caveman token validate openai # 输出[caveman] Token openai is VALID.validate命令会执行你配置的healthCheck函数向 OpenAI API 发送一个真实的请求以确认 token 的有效性。如果一切顺利你会看到VALID的状态。第四步将caveman集成到你的开发脚本中最后一步是让它真正开始工作。打开你的package.json文件找到scripts部分。将你常用的、需要 AI 或网络认证的脚本替换为caveman npx版本。例如{ scripts: { dev: caveman npx next dev, build: caveman npx next build, test: caveman npx vitest } }现在当你运行npm run dev时caveman会自动为你注入OPENAI_API_KEY并确保它在整个next dev过程中始终有效。整个工作流的搭建就此完成。4.2 高级配置实战应对token exchange failed: token endpoint returned status 403 forbidden: country网络热词中反复出现的token exchange failed: token endpoint returned status 403 forbidden: country是caveman最擅长解决的典型场景。这个错误通常意味着你的请求被 OpenAI 的认证服务器拒绝了原因是你的 IP 地址所属的国家/地区不在其服务许可范围内。caveman的解决方案不是教你如何“绕过”地理限制这涉及合规风险而是提供一套优雅的、符合开发者习惯的“降级与告警”机制。我们来配置一个高级的openaitoken使其能智能应对403错误。首先编辑caveman.config.js为openaitoken 添加一个onError回调// caveman.config.js module.exports { tokens: { openai: { source: env:OPENAI_API_KEY, healthCheck: async (token) { const res await fetch(https://api.openai.com/v1/models, { headers: { Authorization: Bearer ${token} } }); // 关键修改不仅检查 res.ok还要检查具体的 status code if (res.status 403) { const body await res.json(); // 检查错误消息中是否包含 country 关键字 if (body.error?.message?.toLowerCase().includes(country)) { // 抛出一个特定的错误便于后续处理 throw new Error([Geoblocked] OpenAI API is not available in your country. Status: ${res.status}); } } return res.ok; }, // 新增错误处理回调 onError: async (error, token) { console.error([caveman] OpenAI token health check failed:, error.message); // 如果是地理封锁错误执行降级逻辑 if (error.message.includes([Geoblocked])) { // 1. 尝试切换到备用的、支持你所在地区的 AI 服务商 // 这里我们模拟一个切换逻辑 const fallbackConfig { provider: anthropic, model: claude-3-haiku-20240307 }; // 2. 将降级配置写入一个临时文件供你的应用读取 await fs.promises.writeFile( ./.caveman-fallback-config.json, JSON.stringify(fallbackConfig, null, 2) ); // 3. 向终端发送一个醒目的、可操作的提示 console.log(\x1b[33m%s\x1b[0m, ⚠️ [caveman] Geoblocking detected!); console.log( Your OpenAI API is unavailable. Falling back to Anthropic.); console.log( Your app can now read ./caveman-fallback-config.json for the new config.); } } } } };这个配置实现了三层防御第一层检测healthCheck函数不再只是简单地判断res.ok而是深入解析403响应体精准识别country相关的错误。第二层响应onError回调被触发它执行一个“降级”Fallback逻辑。这个逻辑不是硬编码的而是高度可定制的它可以写入一个配置文件、发送一个 Slack 通知、甚至调用一个内部的“合规网关”API 来获取一个合法的替代方案。第三层通知它向开发者终端输出一个带有颜色的、醒目的警告\x1b[33m是黄色 ANSI 转义序列并给出清晰的下一步操作指引。现在当你运行caveman token validate openai时如果遇到403 Forbidden: countrycaveman不会静默失败而是会执行上述完整的降级流程。你的应用代码只需要在启动时检查是否存在./.caveman-fallback-config.json文件如果存在就加载其中的配置从而无缝切换到备用 AI 服务商。这种将“基础设施错误”转化为“应用层可处理事件”的能力是caveman区别于其他工具的核心竞争力。4.3 CI/CD 流水线集成在 GitHub Actions 中安全地使用caveman将caveman引入 CI/CD 环境是其价值的终极体现。它能将你在本地精心维护的 token 管理策略100% 复制到自动化构建环境中彻底杜绝npx playwright install失败或login server error: token exchange failed这类在 CI 中频发的“环境差异”问题。以下是一个完整的 GitHub Actions 工作流示例.github/workflows/ci.yml展示了如何在ubuntu-latestrunner 上安全、高效地使用cavemanname: CI Pipeline on: push: branches: [main] pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest steps: # 1. 检出代码 - uses: actions/checkoutv4 # 2. 设置 Node.js 环境 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 # 3. 全局安装 caveman - name: Install caveman run: npm install -g caveman # 4. 将 GitHub Secrets 注入为环境变量安全 # 这是 GitHub Actions 的最佳实践Secrets 不会出现在日志中 - name: Set up environment variables run: | echo OPENAI_API_KEY${{ secrets.OPENAI_API_KEY }} $GITHUB_ENV echo NPM_REGISTRY_TOKEN${{ secrets.NPM_REGISTRY_TOKEN }} $GITHUB_ENV # 5. 初始化 caveman 配置可选如果配置文件已提交 # 如果你的 caveman.config.js 已在代码库中此步可省略 # - name: Initialize caveman config # run: caveman init --yes # 6. 【关键步骤】验证所有 token # 这一步会执行 healthCheck确保所有凭证在 CI 环境中有效 - name: Validate tokens with caveman run: caveman token validate --all # 7. 使用 caveman npx 运行构建命令 # caveman 会自动将 OPENAI_API_KEY 等注入到 npx 子进程中 - name: Build with caveman run: caveman npx next build # 8. 【可选】将本地生成的 token 状态同步到 CI # 例如将一个由本地命令生成的临时 token 同步过来 # -