Freebuff 构建指南:用编译期标志从 Codebuff CLI 剥离出免费版终端编码 Agent

Freebuff 构建指南:用编译期标志从 Codebuff CLI 剥离出免费版终端编码 Agent Freebuff 构建指南用编译期标志从 Codebuff CLI 剥离出免费版终端编码 Agent【免费下载链接】freebuffThe free coding agent项目地址: https://gitcode.com/GitHub_Trending/cod/freebuff导读本篇文章基于仓库中的 freebuff/SPEC.md 产品级技术规格系统讲解 Freebuff —— Codebuff CLI 的仅免费变体——是如何在不维护第二套代码库的前提下通过一个编译期环境变量FREEBUFF_MODE将订阅、积分、模式切换等付费能力从构建产物中剥离的。你将掌握编译期标志的注入机制与死代码消除原理、品牌与 CLI 命令面的条件切换、斜杠命令与输入模式的过滤清单、信用/订阅 UI 的抑制策略、广告常开不可关行为、npm 发布包与 GitHub Workflow 的搭建方式以及配套的单元、集成与 tmux E2E 测试方案。文章同时结合仓库源码给出每一处改动对应的真实文件路径便于你对照阅读与二次开发。1. 总体架构一个代码库两种二进制Freebuff 不是 Codebuff 的 fork而是复用整个cli/包、通过编译期标志裁剪出来的独立 npm 包包名freebuff。它的核心思想是在bun build时通过--define注入process.env.FREEBUFF_MODEtrue让源码中所有if (!IS_FREEBUFF)分支在打包阶段被 bundler 整体删除dead-code elimination从而只保留 FREE 模式的体验。这种设计带来了三个直接收益单一事实来源CLI 的登录、聊天、Agent 编排、文件引用、Bash 模式等能力只有一份实现Freebuff 与 Codebuff 共享不会出现两个产品行为漂移零运行时开销付费功能分支在编译期就消失二进制里根本没有对应的字符串与代码路径低成本维护新增功能默认进入两个产物只有明确需要区分时才写条件分支。从仓库实际结构看freebuff/目录是一个产品级目录按交付面surface划分子目录freebuff/ ├── SPEC.md # 产品级规格本文对应文档 ├── README.md # 产品级文档 ├── cli/ # CLI 构建与发布基础设施 │ ├── build.ts # 构建脚本设置 FREEBUFF_MODEtrue │ └── release/ │ ├── package.json # npm 包元数据name: freebuff │ ├── index.js # 薄产品配置入口 │ └── README.md # npm 包 README └── web/ # 未来Freebuff 网站代码freebuff/web/或其他交付面可在不重构的前提下与 CLI 并行加入见 freebuff/SPEC.md 第 8 节。2. 编译期标志FREEBUFF_MODE 与 IS_FREEBUFF2.1 环境变量与注入方式FREEBUFF_MODEtrue构建时设置用于产出 Freebuff 二进制注入方式bun build的--define process.env.FREEBUFF_MODEtrue与CODEBUFF_IS_BINARY、CODEBUFF_CLI_VERSION的注入模式完全一致。2.2 运行时常量共享常量定义在 cli/src/utils/constants.ts/** * Freebuff build-time flag. When true, the CLI is built as Freebuff (free-only variant). * Injected via --define at compile time; enables dead-code elimination by the bundler. */ export const IS_FREEBUFF getCliEnv().FREEBUFF_MODE true这里getCliEnv()来自 cli/src/utils/env.ts负责读取注入的编译期环境变量。由于--define在编译期就把FREEBUFF_MODE替换成了字面量字符串true或false因此IS_FREEBUFF在打包时即为常量所有依赖它的if分支可被可靠地摇树删除。值得注意的进阶用法同一个常量还驱动了模式到 Agent/计费方式的映射。在 cli/src/utils/constants.ts 中export const AGENT_MODE_TO_ID { DEFAULT: HARNESS_MODE_IDS[CLI_HARNESS].DEFAULT, LITE: IS_FREEBUFF ? base2-free : HARNESS_MODE_IDS[CLI_HARNESS].LITE, MAX: base2-max, PLAN: base2-plan, } as const export const AGENT_MODE_TO_COST_MODE { DEFAULT: normal, LITE: IS_FREEBUFF ? free : lite, MAX: max, PLAN: normal, } as const即Freebuff 的 LITE 模式映射到免费根 Agentbase2-free与free计费模式而普通 Codebuff 的 LITE 映射到付费的base2-lite与lite计费模式计费、会话门槛与地区限制均不同。2.3 build-binary.ts 的改动cli/scripts/build-binary.ts 中FREEBUFF_MODE被加入defineFlags数组const defineFlags [ [process.env.NODE_ENV, production], [process.env.CODEBUFF_IS_BINARY, true], [process.env.CODEBUFF_CLI_VERSION, ${version}], [process.env.CODEBUFF_CLI_TARGET, ${getCliTargetLabel(targetInfo)}], // Freebuff mode flag [process.env.FREEBUFF_MODE, ${process.env.FREEBUFF_MODE ?? false}], ...nextPublicEnvVars, ]脚本同时收集所有NEXT_PUBLIC_*环境变量注入编译产物并支持自定义二进制名参数binaryNameArg ?? codecane这为 Freebuff 产出名为freebuff的二进制提供了基础。3. 品牌替换从 Codebuff 到 Freebuff 的全部界面触点SPEC 给出了完整的品牌映射表涵盖终端标题、CLI 命令名、npm 包名、二进制名、应用头部文案、ASCII Logo、描述与主页区域CodebuffFreebuff终端标题前缀Codebuff:Freebuff:CLI commander 名称codebufffreebuffnpm 包名codebufffreebuff二进制名codebufffreebuff应用头部文案Codebuff will run commands on your behalf to help you build.Freebuff will run commands on your behalf to help you build.ASCII LogoCODEBUFF块字母FREEBUFF块字母新 Logo描述AI coding agentFree AI coding assistant主页codebuff.comcodebuff.com/free或相同WEBSITE_URL用法指向 codebuff.com相同登录、反馈等仍留在 codebuff.com对应到源码的四个修改点均以IS_FREEBUFF为条件cli/src/utils/terminal-title.tsconst TITLE_PREFIX IS_FREEBUFF ? Freebuff: : Codebuff: 。该文件使用 OSCOperating System Command转义序列\x1b]0;${title}\x07设置窗口标题并针对 tmux\x1bPtmux;...与 GNU screen\x1bP...做 DCS 透传标题最长 60 字符cli/src/login/constants.ts新增LOGO_FREEBUFFASCII 艺术变体按IS_FREEBUFF选择cli/src/app.tsx条件化头部文案cli/src/index.tsx 与 cli/src/cli-args.tscommander 的.name(freebuff)、.description(Freebuff - Free AI coding assistant)。CLI 参数解析的差异在 cli/src/cli-args.ts 中体现得非常清晰Freebuff 分支只保留--continue、--cwd、--version、-h/--help与login子命令去掉了--agent、--clear-logs、--lite、--free、--max、--plan和自由 prompt 参数并且initialMode被硬编码为LITEif (isFreebuff) { initialMode LITE } else { if (options.free || options.lite) initialMode LITE if (options.max) initialMode MAX if (options.plan) initialMode PLAN }4. 模式限制Freebuff 只有 FREEFreebuff 仅支持 FREE 模式所有模式相关能力被剥离agentMode恒为FREE永不变化初始模式标志--free、--max、--plan在 Freebuff 中被移除模式被硬编码聊天历史中永远不会插入模式分隔消息mode divider。对应修改点cli/src/components/agent-mode-toggle.tsxIS_FREEBUFF时返回null整个隐藏cli/src/components/build-mode-buttons.tsxIS_FREEBUFF时返回null隐藏消息 UI 中的模式切换按钮cli/src/components/mode-divider.tsxIS_FREEBUFF时返回null不渲染模式转换标记cli/src/utils/input-modes.tsIS_FREEBUFF时将所有输入模式配置的showAgentModeToggle置为false// In Freebuff, never show the agent mode toggle if (IS_FREEBUFF) { for (const key of Object.keys(INPUT_MODE_CONFIGS) as InputMode[]) { INPUT_MODE_CONFIGS[key].showAgentModeToggle false } }cli/src/state/chat-store.ts默认agentMode为FREEIS_FREEBUFF时setAgentMode为 no-opcli/src/index.tsx 与 cli/src/cli-args.ts移除模式 CLI 标志并硬编码初始模式。5. 斜杠命令删除清单与保留清单5.1 移除的命令及其理由命令理由/subscribe/strong、/sub、/buy-credits无订阅模型/usage/credits无积分展示/ads:enable广告常开不可切换/ads:disable广告常开不可切换/connect:claude/claudeClaude 订阅不可用/refer-friends/referral、/redeem推荐奖励积分不适用/mode:*全部模式命令仅 FREE 模式/agent:gpt-5高级 Agent免费档不可用/review在所选模型上评审/publishAgent 发布在免费档不可用/image/img、/attach非多模态免费模型DeepSeek V4 Pro、DeepSeek V4 Flash不支持图片附件5.2 保留的命令命令说明/help帮助内容已修改见 §7/new/clear、/reset、/n、/c清空会话/history/chats浏览历史会话/feedback/bug、/report反馈/bash/!Bash 模式/theme:toggle亮/暗切换/logout/signout登出/exit/quit、/q退出/login/signin已登录提示Skill 命令/skill:*若已加载技能则保留5.3 实现双集合过滤cli/src/data/slash-commands.ts 中定义了两个集合与最终的过滤逻辑const FREEBUFF_REMOVED_COMMAND_IDS new Set([ ads:enable, ads:disable, usage, subscribe, agent:gpt-5, image, publish, init, ]) const FREEBUFF_ONLY_COMMAND_IDS new Set([ byok, plan, end-session, dashboard, reasoning, ]) export const SLASH_COMMANDS IS_FREEBUFF ? ALL_SLASH_COMMANDS.filter((cmd) !FREEBUFF_REMOVED_COMMAND_IDS.has(cmd.id)) : ALL_SLASH_COMMANDS.filter((cmd) !FREEBUFF_ONLY_COMMAND_IDS.has(cmd.id))注意两点MODE_COMMANDS在IS_FREEBUFF时直接生成空数组const MODE_COMMANDS: SlashCommand[] IS_FREEBUFF ? [] : ...而byok、plan、end-session、dashboard、reasoning是 Freebuff 独有的命令在普通 Codebuff 中反而被过滤。getSlashCommandsWithSkills()会将技能映射为skill:*命令追加到列表末尾。命令执行注册表 cli/src/commands/command-registry.ts 采用类似策略被移除的命令用!IS_FREEBUFF守卫包裹。6. 信用与订阅 UI整体抑制Freebuff 永不展示积分、用量、订阅信息或积分耗尽状态。6.1 抑制的组件IS_FREEBUFF时渲染null组件文件行为UsageBannercli/src/components/usage-banner.tsx永不渲染OutOfCreditsBannercli/src/components/out-of-credits-banner.tsx永不渲染SubscriptionLimitBannercli/src/components/subscription-limit-banner.tsx永不渲染BottomStatusLinecli/src/components/status-bar.tsx永不渲染Claude 订阅状态消息页脚中的积分cli/src/components/message-footer.tsx移除CreditsOrSubscriptionIndicator不显示积分或 ✓ StrongClaudeConnectBannercli/src/components/login-modal.tsx永不渲染6.2 不可达的输入模式IS_FREEBUFF时下列输入模式不可达outOfCredits—— 永不触发subscriptionLimit—— 永不触发usage—— 无/usage命令connect:claude—— 无/connect:claude命令referral—— 无/refer-friends命令。从 cli/src/utils/input-modes.ts 的类型定义可看到完整模式枚举default | bash | homeDir | plan | review | interview | skill | usage | image | help | outOfCredits | subscriptionLimit其中subscriptionLimit模式的blockKeyboardExit: true在 Freebuff 中永不生效。6.3 跳过的 Hookscli/src/hooks/use-usage-monitor.tsIS_FREEBUFF时直接返回无积分可监控。源码中useUsageQuery({ enabled: !IS_FREEBUFF })与if (IS_FREEBUFF) return双重保险cli/src/hooks/use-subscription-query.tsIS_FREEBUFF时返回空/禁用cli/src/hooks/use-claude-quota-query.tsIS_FREEBUFF时返回空/禁用cli/src/hooks/use-usage-query.ts仍需要——服务端计费仍在使用只是 UI 永不展示。6.4 会话积分跟踪sessionCreditsUsed在 cli/src/state/chat-store.ts 中仍会累积服务端跟踪用量但 UI 永不显示chat.tsx中的广告横幅继续以isFreeMode{true}硬编码传递。7. 帮助菜单去掉 Credits 区块Freebuff 的/help横幅被简化移除整个Credits区块。最终内容如下Shortcuts CtrlC / Esc stop CtrlJ / OptEnter newline ↑↓ history CtrlT collapse/expand agents Features / commands files mention agents use agent !bash run command没有 Credits 区块没有/subscribe、/usage、/ads:enable引用。对应文件为 cli/src/components/help-banner.tsxIS_FREEBUFF时条件隐藏 Credits 区块。8. 广告行为常开且不可关闭在 Freebuff 中广告始终启用且不可关闭有可用广告时横幅总是渲染信息面板中的 Hide ads 链接被替换为 Ads are required in Free mode.该文案在ad-banner.tsx的isFreeMode为 true 时已存在/ads:enable与/ads:disable命令被移除见 §5getAdsEnabled()在IS_FREEBUFF时总是返回true。核心实现见 cli/src/commands/ads.tsexport const getAdsEnabled (): boolean { if (IS_FREEBUFF) return true // Codebuff LITE is a paid mode now, so use the normal saved setting. const settings loadSettings() return settings.adsEnabled ?? false }cli/src/chat.tsx 中跳过!hasSubscription的广告守卫始终展示。免费模式的端到端验证可在 freebuff/e2e/tests/ads-behavior.e2e.test.ts 中看到启动后输入/ads检查自动补全中不出现ads:enable/ads:disable且启动画面不包含N credits、Hide ads 等字样。9. 构建与发布产品级目录与 npm 包9.1 构建脚本freebuff/cli/build.tsfreebuff/cli/build.ts 是对 cli/scripts/build-binary.ts 的薄封装FREEBUFF_MODEtrue bun cli/scripts/build-binary.ts freebuff version实际实现使用spawnSync(bun, [cli/scripts/build-binary.ts, freebuff, version], { cwd: repoRoot, env: { ...process.env, FREEBUFF_MODE: true } })任何非零退出码都会使构建失败。构建完成后二进制输出在cli/bin/下Windows 为freebuff.exe。9.2 发布包freebuff/cli/release/package.json镜像cli/release/package.json但关键字段不同实际仓库 freebuff/cli/release/package.jsonname: freebuffdescription: The worlds strongest free coding agentSPEC 中规划为 Free AI coding assistant实际发布元数据以仓库现状为准bin: { freebuff: index.js }files: [index.js, launcher.js, http.js, README.md]os: [darwin, linux, win32]、cpu: [x64, arm64]engines: { node: 16 }prepack: node ../../../cli/release-core/prepare-package.jspostpack执行清理发布入口 freebuff/cli/release/index.js 是薄配置优先使用打包时物化的launcher.js否则回退到源码树中的 cli/release-core/launcher.js并用createLauncher({ packageName: freebuff, displayName: Freebuff, wrapperVersion: ... })创建启动器。启动器会在首次运行时下载平台对应二进制二进制存放于~/.config/manicode/freebuffWindows 上为freebuff.exe。9.3 发布脚本与 GitHub Workflowfreebuff/cli/release.ts 通过workflow_dispatch触发freebuff-release.yml用法bun freebuff/cli/release.ts [patch|minor|major] [--ref commit-sha]需要CODEBUFF_GITHUB_TOKEN环境变量。Workflow 镜像cli-release-prod.yml关键差异二进制名freebuff、版本来源freebuff/cli/release/package.json、Git tagfreebuff-vversion、npm 发布freebuff包、环境覆盖{FREEBUFF_MODE: true, NEXT_PUBLIC_CB_ENVIRONMENT: prod}。10. 保持不变的功能下列功能在 Freebuff 中与 Codebuff 完全一致认证—— 登录/登出流程、API Key 存储聊天—— 消息历史、流式输出、Agent 派生文件引用files—— 浏览与附加文件Agent 引用agents—— 使用可用 Agent仅免费档 AgentBash 模式—— 运行终端命令图片附件—— 附加与粘贴图片知识文件——knowledge.md聊天历史——/history、恢复会话反馈——/feedback命令主题—— 亮/暗切换技能—— 从.agents/skills加载本地 Agent—— 从.agents/目录加载。11. 分析与服务端考量11.1 分析事件IS_FREEBUFF时APP_LAUNCHED事件包含isFreebuff: true见 cli/src/index.tsx事件字段名为isFreeBuff所有既有分析事件继续触发用于对比免费与付费用量初期无需新增分析事件。此外 cli/src/index.tsx 在 Freebuff 下会启动startEngagementTracking()engaged-time 心跳与 MESSAGE_SENT DAU 信号对应并在 Windows 平台提前drainClientLogs()。11.2 服务端服务端已正确处理 FREE 模式无需改动common/src/constants/free-agents.ts 中的FREE_COST_MODE free识别free计费模式AGENT_MODE_TO_COST_MODE.FREE free已配置免费模式允许的 Agent模型组合计 0 积分FREE 模式下的广告展示不产生积分。唯一的例外发布下载 API/api/releases/download/必须能提供freebuff-*二进制 tarball可能需要更新下载路由以识别 Freebuff 发布 tagfreebuff-v*。12. 测试策略12.1 单元测试测试IS_FREEBUFF守卫是否正确隐藏/显示组件测试过滤后的斜杠命令列表测试过滤后的命令注册表测试帮助横幅内容。12.2 集成测试构建 Freebuff 二进制并验证标题显示 Freebuff无模式切换可见/subscribe、/usage命令不存在帮助菜单无 Credits 区块广告始终显示。12.3 E2Etmux使用codebuff-local-cliAgent 配合FREEBUFF_MODEtrue验证视觉输出。仓库中的实际验证设施包括freebuff/cli/smoke-test.test.ts直接对cli/bin/freebuff二进制做冒烟测试——--version输出合法 semver--help包含Usage: freebuff与Free AI coding assistant且不含Usage: codebuff--help中不存在--free/--max/--plan/--litelogin子命令进入登录流程tmux 捕获画面断言 Freebuff ASCII Logo█████╗ ██████╔╝的 FR 特征行而非 Codebuff Logo██╔════╝██╔═══██╗freebuff/e2e/tests/ 下的 tmux E2E 套件ads-behavior、slash-commands、help-command、startup、version、knowledge-file、code-edit、live-turn、terminal-command、agent-startup配合 freebuff/e2e/utils/ 中的FreebuffSession与requireFreebuffBinary工具。13. 实施阶段路线图Phase 1核心标志与品牌添加IS_FREEBUFF常量更新build-binary.ts透传FREEBUFF_MODE条件品牌标题、Logo、应用头部、CLI 名。Phase 2功能剥离过滤斜杠命令与命令注册表隐藏 Agent 模式切换抑制积分/订阅 UI 组件禁用用量监控 Hook简化帮助横幅。Phase 3广告与收尾广告常开行为禁用不可达输入模式隐藏BuildModeButtons与ModeDivider组件。Phase 4构建与发布基础设施创建freebuff/cli/release/包文件创建freebuff/cli/build.ts脚本创建.github/workflows/freebuff-release.yml。Phase 5测试添加IS_FREEBUFF守卫的单元测试添加集成/E2E 测试手动 QA 构建出的二进制。14. 从源码验证一个 Freebuff 事实以--help不包含模式标志为例链路为IS_FREEBUFFtrue→ cli/src/cli-args.ts 中parseArgs的 Freebuff 分支只注册--continue/--cwd/--version/-h→ commander 生成的帮助文本自然不含--free/--max/--plan/--lite→ freebuff/cli/smoke-test.test.ts 中expect(output).not.toMatch(/--free\b/)等断言锁定该行为。这表明 SPEC 中硬编码 LITE、移除模式标志的设计不止停留在文档而是被参数解析与冒烟测试双重固化。结语Freebuff 是编译期特性裁剪思路在终端 AI 编码 Agent 上的一次完整落地一个共享 CLI 代码库通过FREEBUFF_MODE编译期标志产出免费版二进制同时用品牌映射、命令过滤、UI 抑制、广告常开和独立的 npm 发布链路保证免费体验的自洽性。对照 freebuff/SPEC.md 与cli/src、freebuff/cli、common/src/constants/free-agents.ts等源码阅读可以完整还原从一行环境变量到整条发布管线的全部实现路径。【免费下载链接】freebuffThe free coding agent项目地址: https://gitcode.com/GitHub_Trending/cod/freebuff创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考