logo
0
0
WeChat Login
docs: 添加 Hermes Agent 安装与 OAuth 登录教程 + CodeBuddy/CNB 环境变量

CNB 云原生开发环境浏览器兼容性白屏问题 — 技术调查报告

报告日期:2026-04-15 调查人:CodeBuddy 关联仓库:cnb/cool/cnb-welcome、cnb/cool/default-dev-env


一、情绪与心流记录

1.1 初始接收 — 好奇与紧迫感

收到这个问题时,第一反应是好奇。用户描述的现象非常精准:特定浏览器(华为 Chrome 114、Kiwi Chrome 132)在特定时间点(4月13日)之后开始白屏,而同一浏览器用旧版环境正常,微信内置浏览器也正常。这种"时间分界线"式的 bug 描述,是最容易定位根因的类型——只需要找到那个时间点前后的代码变更。

同时有一种紧迫感,因为这影响的是用户的核心体验:白屏意味着完全无法使用 codebuddy,这不是体验降级,而是功能完全不可用。

1.2 第一步调查 — 方向确认

先查了当前工作区 /workspace 的 git log。发现这是 default-dev-env 仓库(fork 自 cnb/cool/default-dev-env),而 upstream/main 的最后提交是 2026-03-09,4月13日前后没有任何变更。

这一刻内心有一点短暂的困惑——用户说"4月13日更新",但 default-dev-env 没有更新?随即意识到用户同时提到了两个项目:cnb-default-envcnb-welcome。Dockerfile 中 code-server --install-extension cnbcool.cnb-welcome 表明 cnb-welcome 是作为 VSCode 扩展安装的,扩展版本更新不需要 Docker 镜像重建——扩展市场的版本更新是独立的。

这个认知转换很关键:问题不在 Docker 镜像的 git 历史,而在 cnb-welcome 扩展的版本发布历史

1.3 第二步调查 — 锁定嫌疑人

通过 CNB OpenAPI 查询 cnb/cool/cnb-welcome 的提交记录,看到了一条清晰的时间线:

322d7440 2026-04-15 chore(release): 1.4.0 42d3a552 2026-04-15 feat: light模式下样式适配 9bc35106 2026-04-13 chore(release): 1.3.0 ← 分界点 9fb8900c 2026-04-09 feat: 新增倒计时功能 e84810a7 2026-04-07 feat: 新增侧边栏和左边栏 ← 根因 f8ab2cce 2026-03-10 fix(doc): 修正 README typo

兴奋点来了:4月7日之前是正常的,4月7日有"新增侧边栏",4月9日有"新增倒计时",4月13日发版 1.3.0。用户说的"4月13日开始出问题",实际上代码变更在4月7日就已经引入,只是4月13日才发布为 1.3.0 版本。

1.4 第三步调查 — 深入 diff

查看 PR #46 的文件变更列表:

package.json — 新增 activitybar 视图容器 api.ts — 新增关闭环境 API constant.ts — 新增常量 register.ts — 注册侧边栏 Provider sidebar-manage.ts — 新文件,106行 util.ts — 新增漫游文件功能 extension.ts — 引入侧边栏注册 sidebar.html — 新文件,100行 ← 重点 sidebar.js — 新文件,306行

拿到 sidebar.html 的完整内容时,心流达到峰值——一眼看到了问题所在:

<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>

就是这一行。Tailwind CSS Play CDN + container-queries 插件。在 VSCode webview 里加载运行时 CSS 编译器,还带了容器查询插件。

1.5 交叉验证 — 信心确认

确认 welcome/index.html(主欢迎页面)没有使用 Tailwind CDN——它用的是纯 CSS。这意味着白屏不是欢迎页的问题,而是侧边栏 webview 的渲染失败级联影响了整个 VSCode 侧边栏

再看 sidebar.js 的内容——纯原生 JS,没有任何现代语法问题(没有 optional chaining、没有 using、没有 top-level await)。所以 JS 本身不是问题,问题出在 HTML 加载 Tailwind CDN 这一步

这时完全确信了结论。

1.6 情绪总结

整个调查过程的心流曲线:

好奇 ──→ 困惑(找错仓库) ──→ 顿悟(扩展独立更新) ──→ 兴奋(时间线吻合) ──→ 峰值(一眼定位) ──→ 确信(交叉验证)

从开始到定位,关键是三个认知跳跃:

  1. Docker 镜像没更新 ≠ 扩展没更新
  2. 4月13日发布 ≠ 4月13日改代码(代码变更更早)
  3. webview 白屏 ≠ 只是这个 webview 白屏(可能级联阻塞整个侧边栏)

二、问题现象

浏览器内核版本4月13日前4月13日后
华为浏览器Chrome 114✅ 正常❌ 白屏
Kiwi 浏览器Chrome 132✅ 正常❌ 白屏
微信内置浏览器较新 Chromium✅ 正常✅ 正常
旧版自定义环境 (4月7日前)任意✅ 正常✅ 正常

用户 UA 详细信息:

  • Kiwi: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36
  • 华为: Mozilla/5.0 (Linux; Android 14; REA-AN00; HMSCore 6.15.0.309; GMSCore 24.31.37) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.9.300 Mobile Safari/537.36

三、根因分析

3.1 直接原因

cnb-welcome 扩展 PR #46(4月7日合并)新增的 src/sidebar/sidebar.html 文件中,引入了 Tailwind CSS Play CDN:

<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>

3.2 为什么这会导致白屏

问题 1:Tailwind CSS Play CDN 是开发工具,非生产用途

cdn.tailwindcss.com 加载的是 Tailwind CSS 的运行时编译器(Play CDN),它的工作原理是:

  1. 下载一个 ~300KB 的 JavaScript 运行时
  2. 扫描 HTML 中的 class 名称
  3. 在浏览器中实时生成对应的 CSS
  4. 将 CSS 注入到 <style> 标签中

这个运行时编译器使用了大量现代 JavaScript 特性,包括但不限于:

  • 较新的 CSS 解析和生成 API
  • 动态 CSSStyleSheet 操作
  • 可能的 structuredCloneusing 等较新 API
  • 复杂的正则表达式和字符串处理

Chrome 114 的 JavaScript 引擎无法正确执行此编译器,导致脚本执行异常,webview 渲染中断,表现为白屏。

问题 2:container-queries 插件

?plugins=forms,container-queries 中的 container-queries 插件依赖 CSS Container Queries 特性:

  • @container 规则:Chrome 105+ 支持
  • container-type 属性:Chrome 105+ 支持
  • 但即使 Chrome 132 支持 Container Queries,Tailwind CDN 运行时本身的问题仍然会导致白屏

问题 3:外网 CDN 依赖

在 VSCode webview 中加载 cdn.tailwindcss.comfonts.googleapis.com 存在额外风险:

  • 网络不通时,<script> 标签加载失败 → Tailwind 未定义 → 后续 JS 执行错误
  • CSP (Content Security Policy) 可能阻止外部脚本加载
  • CDN 不可用时无任何 fallback,直接白屏

问题 4:级联影响

VSCode 侧边栏中,cnb-welcome 注册了一个 activitybar 视图容器(侧边栏图标)和一个 webview 视图。当这个 webview 渲染失败时,可能导致:

  • 侧边栏面板区域白屏
  • 与 codebuddy 插件的侧边栏面板产生交互问题
  • 整个侧边栏渲染阻塞

3.3 为什么 Kiwi (Chrome 132) 也白屏

Chrome 132 理论上支持 Tailwind CDN 所需的 JS 特性,但白屏可能由以下原因导致:

  1. CDN 加载失败:网络原因导致 cdn.tailwindcss.com 无法访问
  2. webview 环境差异:Kiwi 浏览器对 webview 的实现可能有 CSP 限制或其他差异
  3. Google Fonts 加载失败:外网字体加载超时阻塞渲染

3.4 为什么微信内置浏览器正常

微信内置浏览器基于较新的 Chromium 内核,且微信对 webview 的网络代理和 CSP 策略可能与 Kiwi/华为浏览器不同,使得 CDN 资源可以正常加载和执行。

3.5 为什么旧版自定义环境正常

旧版自定义环境使用的是 cnb-welcome 1.2.x 版本,该版本没有侧边栏功能,不包含 Tailwind CDN 依赖。


四、变更时间线

日期版本提交变更内容影响
2026-03-101.2.2f8ab2cce修正 README typo
2026-04-07-e84810a7新增侧边栏和左边栏 (PR #46)⚠️ 引入 Tailwind CDN
2026-04-09-9fb8900c新增倒计时功能 (PR #47)扩展 sidebar.html
2026-04-131.3.09bc35106版本号修改正式发布含问题的版本
2026-04-15-42d3a552light 模式样式适配仍有 Tailwind CDN
2026-04-151.4.0322d7440版本号修改仍有 Tailwind CDN

五、修复建议

5.1 方案 A:移除 Tailwind CDN,改用构建时编译(推荐)

将 Tailwind CSS 从运行时 CDN 改为 webpack 构建时编译:

  1. npm install -D tailwindcss postcss autoprefixer
  2. 配置 tailwind.config.jspostcss.config.js
  3. 创建 src/sidebar/sidebar.css,使用 @tailwind 指令
  4. webpack.config.js 中添加 PostCSS loader
  5. sidebar.html 中用构建产物 <link> 替换 CDN <script>
  6. 移除 cdn.tailwindcss.com<script id="tailwind-config"> 配置块

优点:生产级方案,CSS 在构建时生成,无运行时开销,无浏览器兼容性问题 缺点:需要修改构建配置

5.2 方案 B:手写 CSS 替代 Tailwind

侧边栏页面并不复杂(约100行 HTML),完全可以手写 CSS:

  1. 将 Tailwind class 转换为等价的自定义 CSS
  2. 移除 Tailwind CDN 依赖
  3. 移除 Google Fonts CDN,使用系统字体栈

优点:最简单,无构建配置变更,无外部依赖 缺点:后续维护样式不如 Tailwind 方便

5.3 方案 C:添加 fallback 和错误处理(临时方案)

如果短期内无法重构,可添加防御性代码:

<!-- 在 Tailwind CDN 加载失败时提供 fallback --> <script> window.__tailwindLoaded = false; </script> <script src="https://cdn.tailwindcss.com?plugins=forms,container-queries" onload="window.__tailwindLoaded=true" onerror="console.warn('Tailwind CDN failed, using fallback styles')"> </script> <style> /* 核心 fallback 样式 */ .fallback-hidden { display: none; } </style>

优点:快速止血 缺点:治标不治本,仍有网络依赖

5.4 通用建议

  1. 移除 Google Fonts CDN 依赖:将 Inter 字体和 Material Symbols 图标打包进扩展资源
  2. 添加 browserslist 配置:确保构建产物兼容目标浏览器版本
  3. VSCode 扩展 webview 最佳实践:不应依赖外部 CDN 资源,所有资源应通过 webview.asWebviewUri() 加载本地文件

六、相关 Issues

Issue描述关联度
#3521加载 Web 视图时出错:ServiceWorker 注册失败,cnb welcome 页面空白高度相关,可能是同一 webview 渲染问题
#3344codebuddy 界面无法加载显示相关,但原因是扩展 API 报错
#3630 / #3613微信浏览器兼容性问题相关,特定浏览器表现异常

七、验证方法

修复后,可通过以下方式验证:

  1. 在华为浏览器 (Chrome 114) 上打开默认开发环境,确认侧边栏和 codebuddy 正常加载
  2. 在 Kiwi 浏览器 (Chrome 132) 上重复验证
  3. 断网状态下打开开发环境,确认侧边栏不白屏(验证无外部 CDN 依赖)
  4. 在 Chrome DevTools 中将 JavaScript 执行降级到 ES2020,确认无兼容性问题

本报告基于对 cnb/cool/cnb-welcome 仓库 git 提交历史、PR #46/#47 文件变更、以及 sidebar.html/sidebar.js 源码的完整分析。


八、侧边栏功能工作机制详解

8.1 数据来源 — 环境变量

constant.ts 中从 process.env 读取关键变量:

// 最长可用时间(毫秒) CNB_VSCODE_MAX_RUN_TIME = '', // 构建开始时间(UTC格式) CNB_BUILD_START_TIME = '', // CPU 核数 CNB_CPUS = '', // 内存大小 CNB_MEMORY = '',

这些环境变量由 CNB 平台在启动开发环境时注入。

8.2 数据传递 — Handlebars 模板渲染

sidebar-manage.tsCnbSidebarProvider 使用 Handlebars 模板引擎,将环境变量注入到 sidebar.html 的占位符中:

// sidebar-manage.ts 中的 resolveWebviewView 方法 this.compiledTemplate = Handlebars.compile(templateHtml); const html = this.compiledTemplate({ maxRunTime: CNB_VSCODE_MAX_RUN_TIME, buildStartTime: CNB_BUILD_START_TIME, cpus: CNB_CPUS, memory: CNB_MEMORY, usageGuildDocUri: `https://docs.${CNB_WEB_HOST}/zh/...`, customEnvDocUri: `https://docs.${CNB_WEB_HOST}/zh/...`, workspaceRecycleDocUri: `https://docs.${CNB_WEB_HOST}/zh/...`, jsUri: /* sidebar.js 的 webview URI */ });

8.3 倒计时渲染 — 前端 JS 计算

sidebar.html 中通过 data- 属性将数据传给前端 JS:

<div id="countdown-section" data-max-run-time="{{maxRunTime}}" data-build-start-time="{{buildStartTime}}">

sidebar.js 中的 handleCountdown() 函数读取这些属性并计算剩余时间:

function handleCountdown() { const section = document.getElementById('countdown-section'); const maxRunTime = parseInt(section.dataset.maxRunTime); // 最长可用时间(ms) const buildStartTime = section.dataset.buildStartTime; // 构建开始时间(UTC) const startMs = new Date(buildStartTime).getTime(); const endMs = startMs + maxRunTime; // 到期时间 const WARNING_THRESHOLD = 30 * 60 * 1000; // 30分钟预警 function update() { const now = Date.now(); const remaining = endMs - now; // 计算 时:分:秒 并显示 // 剩余 ≤ 30分钟 → 红色警告 // 剩余 ≤ 0 → 显示"已到期,即将被回收" } update(); setInterval(update, 1000); // 每秒刷新 }

8.4 侧边栏功能模块总览

模块数据来源交互方式
系统信息(CPU/内存)CNB_CPUSCNB_MEMORY 环境变量纯展示
回收倒计时CNB_BUILD_START_TIME + CNB_VSCODE_MAX_RUN_TIME每秒刷新,<30分钟红色警告
关闭环境调用 SHUTDOWN_ENV_URL API(${CNB_API_ENDPOINT}/${CNB_REPO_SLUG}/-/build/stop点击按钮 → vscode.postMessage({type:"shutdown"})
文件漫游读取 /run/.userdata/ 目录树懒加载,点击展开子目录
文档链接拼接 https://docs.${CNB_WEB_HOST}/zh/...点击跳转

8.5 消息通信机制

侧边栏 webview 与 VSCode 扩展之间通过 postMessage 通信:

sidebar.js (webview) sidebar-manage.ts (extension) ───────────────── ──────────────────────────── vscode.postMessage({type:"shutdown"}) → 处理关闭环境 API 调用 vscode.postMessage({type:"getRoamingFiles"}) → 读取目录树,回传数据 vscode.postMessage({type:"loadDirectoryChildren", path}) → 懒加载子目录 vscode.postMessage({type:"openFileRoamingHelp"}) → 打开帮助文档

扩展端在 sidebar-manage.tsresolveWebviewView 中监听 onDidReceiveMessage,根据 message.type 分发处理。

8.6 工作流程总结

环境变量 → Handlebars 模板注入 → HTML data 属性 → JS 读取并每秒倒计时,这就是回收倒计时的完整链路。


九、开发环境 process.env 变量清单

以下为当前云原生开发环境(kfc60/default-dev-env)中的 process.env 变量,敏感信息已脱敏(保留末尾4-5位)。

9.1 CNB 平台环境变量

变量名值(脱敏)说明
CNBtrue标识当前在 CNB 环境中
CNB_API_ENDPOINThttps://api.cnb.coolCNB API 地址
CNB_WEB_HOSTcnb.coolCNB Web 域名
CNB_WEB_ENDPOINThttps://cnb.coolCNB Web 地址
CNB_WEB_PROTOCOLhttps协议
CNB_TOKEN*****0BCB认证令牌
CNB_TOKEN_USER_NAMEcnb令牌用户名
CNB_BRANCHmain当前分支
CNB_BRANCH_SHA8a79629...f01f当前分支 SHA
CNB_COMMIT8a79629...f01f当前提交 SHA
CNB_COMMIT_SHORT8a796291短 SHA
CNB_COMMIT_MESSAGEfeat: 安装 cnb-openapi-skills提交消息
CNB_COMMIT_MESSAGE_TITLEfeat: 安装 cnb-openapi-skills提交标题
CNB_COMMITTERsixther提交者
CNB_COMMITTER_EMAIL382998****@qq.com提交者邮箱
CNB_DEFAULT_BRANCHmain默认分支
CNB_EVENTvscode触发事件类型
CNB_BUILD_IDcnb-ggo-1jm8*****构建 ID
CNB_BUILD_START_TIME2026-04-15T12:02:09.041Z构建开始时间(UTC)
CNB_BUILD_USERcnb.ageYeGZgDeAA构建用户
CNB_BUILD_USER_EMAILZVf1wk*****@noreply.cnb.cool构建用户邮箱
CNB_BUILD_USER_ID1938853994086588416构建用户 ID
CNB_BUILD_USER_NICKNAME构建用户昵称
CNB_BUILD_WEB_URLhttps://cnb.cool/kfc60/default-dev-env/-/build/logs/cnb-ggo-1jm8*****构建日志 URL
CNB_BUILD_WORKSPACE/workspace/工作目录
CNB_PIPELINE_IDcnb-ggo-1jm8*****-001流水线 ID
CNB_PIPELINE_MAX_RUN_TIME72000000流水线最长运行时间(ms)= 20小时
CNB_VSCODE_MAX_RUN_TIME64800000VSCode 最长可用时间(ms)= 18小时
CNB_CPUS8CPU 核数
CNB_MEMORY16内存(GiB)
CNB_REPO_ID2044385673280798720仓库 ID
CNB_REPO_NAMEdefault-dev-env仓库名
CNB_REPO_SLUGkfc60/default-dev-env仓库 Slug
CNB_REPO_URL_HTTPShttps://cnb.cool/kfc60/default-dev-env仓库 HTTPS 地址
CNB_FORK_FROM_REPO_SLUGcnb/cool/default-dev-envFork 来源仓库
CNB_GROUP_SLUGkfc60组织 Slug
CNB_RUNNER_IP10.235.16.8Runner IP(内网)
CNB_DOCKER_REGISTRYdocker.cnb.coolDocker 镜像仓库
CNB_DOCKER_MODEL_REGISTRYdocker-model.cnb.coolDocker 模型仓库
CNB_HELM_REGISTRYhelm.cnb.coolHelm 仓库
CNB_VSCODE_WEB_URLhttps://cnb.cool/kfc60/default-dev-env/-/workspace/vscode-web/...VSCode Web 访问地址
CNB_VSCODE_PROXY_URIhttps://l28h9*****-{{port}}.cnb.runVSCode 代理 URI
CNB_VSCODE_REMOTE_SSH_SCHEMAvscode://vscode-remote/ssh-remote+...VSCode Remote SSH 连接串
CNB_WELCOME_CMDecho "Welcome to CNB"欢迎命令
CNB_COMMENT_TYPEnote评论类型
CNB_EVENT_URLhttps://cnb.cool/kfc60/default-dev-env/-/commit/...事件 URL
CNB_IS_CRONEVENTfalse是否定时触发
CNB_IS_NEW_BRANCHfalse是否新分支
CNB_IS_RETRYfalse是否重试
CNB_IS_TAGfalse是否 Tag
CNB_PULL_REQUESTfalse是否 PR
CNB_HAS_LFS_FILESfalse是否有 LFS 文件
CNB_TAG_IS_PRE_RELEASEfalseTag 是否预发布
CNB_TAG_IS_RELEASEfalseTag 是否正式发布

9.2 CodeBuddy / ACC 相关环境变量

变量名说明
ACC_PRODUCT_CONFIG_V2CodeBuddy 产品配置 JSON(含 API endpoint、认证令牌、模型列表)
ACC_USER_IDCodeBuddy 用户 ID
ACC_USER_NICKNAMECodeBuddy 用户昵称

9.3 code-server / VSCode 环境变量

变量名说明
BROWSER/usr/lib/code-server/lib/vscode/bin/helpers/browser.sh浏览器路径
TERM_PROGRAMvscode终端程序
TERM_PROGRAM_VERSION1.112.0VSCode 版本
VSCODE_IPC_HOOK_CLI/tmp/vscode-ipc-*.sockVSCode IPC 通道
VSCODE_GIT_ASKPASS_MAIN.../askpass-main.jsGit 认证辅助
VSCODE_PROXY_URIhttps://l28h9*****-{{port}}.cnb.run/端口代理 URI

9.4 系统环境变量

变量名说明
HOME/root用户目录
HOSTNAME3080392c5fb1容器主机名
LANGC.UTF-8字符集
TZAsia/Shanghai时区
SHELLzsh (oh-my-zsh)默认 Shell
UV_INSTALL_DIR/usr/local/binuv 安装目录

十、VSCode 扩展版本查询与安装教程

10.1 当前环境信息

  • code-server 版本4.112.0(内置 Code 1.112.0)
  • 已安装 cnb-welcome 版本1.2.2(当前环境 fork 自 upstream,Docker 镜像构建时安装的版本)
  • cnb-welcome 最新版本1.4.0(含侧边栏 + Tailwind CDN,即本次报告分析的有问题版本)

10.2 通过 Open VSX Registry 查询扩展版本

Open VSX 是 VSCode 扩展的开放注册中心,code-server 默认从此拉取扩展。API 地址格式:

# 查询扩展信息(最新版本) curl -s "https://open-vsx.org/api/{namespace}/{extension-name}" # 查询特定版本 curl -s "https://open-vsx.org/api/{namespace}/{extension-name}/{version}"

示例 — 查询 cnb-welcome 扩展:

curl -s "https://open-vsx.org/api/cnbcool/cnb-welcome"

返回的 JSON 中关键字段:

  • version:当前最新版本号
  • allVersions:所有可用版本及其 API 地址
  • files.download:vsix 文件下载地址

示例 — 查询 CodeBuddy (coding-copilot) 扩展:

curl -s "https://open-vsx.org/api/tencent-cloud/coding-copilot"

返回结果中 allVersions 列出所有历史版本:

{ "4.3.20019762": "https://open-vsx.org/api/Tencent-Cloud/coding-copilot/4.3.20019762", "4.3.18808231": "https://open-vsx.org/api/Tencent-Cloud/coding-copilot/4.3.18808231", "4.2.16150775": "https://open-vsx.org/api/Tencent-Cloud/coding-copilot/4.2.16150775", "3.12.12929358": "https://open-vsx.org/api/Tencent-Cloud/coding-copilot/3.12.12929358", ... }

10.3 下载指定版本的 vsix 文件

从 Open VSX API 返回的 files.download 字段可直接获取 vsix 下载地址:

# 下载 cnb-welcome 1.2.2(无 Tailwind CDN 的稳定版本) curl -L -o cnb-welcome-1.2.2.vsix \ "https://open-vsx.org/api/cnbcool/cnb-welcome/1.2.2/file/cnbcool.cnb-welcome-1.2.2.vsix" # 下载 coding-copilot 指定版本 curl -L -o coding-copilot-3.12.vsix \ "https://open-vsx.org/api/Tencent-Cloud/coding-copilot/3.12.12929358/file/Tencent-Cloud.coding-copilot-3.12.12929358.vsix"

10.4 安装 vsix 文件到 code-server

# 方式一:通过 code-server CLI 安装 code-server --install-extension /path/to/extension.vsix # 方式二:通过 VSCode 命令安装(在 VSCode 中 Ctrl+Shift+P) # Extensions: Install from VSIX...

10.5 在 Dockerfile 中指定扩展版本

默认 code-server --install-extension cnbcool.cnb-welcome 会安装最新版本。如需锁定版本:

# 方式一:下载 vsix 后 COPY 进镜像 COPY cnb-welcome-1.2.2.vsix /tmp/ RUN code-server --install-extension /tmp/cnb-welcome-1.2.2.vsix && \ rm /tmp/cnb-welcome-1.2.2.vsix # 方式二:在构建时下载指定版本 RUN curl -L -o /tmp/cnb-welcome.vsix \ "https://open-vsx.org/api/cnbcool/cnb-welcome/1.2.2/file/cnbcool.cnb-welcome-1.2.2.vsix" && \ code-server --install-extension /tmp/cnb-welcome.vsix && \ rm /tmp/cnb-welcome.vsix

10.6 cnb-welcome 版本与浏览器兼容性对照

版本侧边栏Tailwind CDN浏览器兼容性
≤ 1.2.2❌ 无❌ 无✅ 所有浏览器正常
1.3.0✅ 有✅ 有❌ Chrome 114 白屏,Chrome 132 可能白屏
1.4.0✅ 有✅ 有❌ 同上

临时修复方案:在 Dockerfile 中锁定 cnb-welcome 为 1.2.2 版本,直到 Tailwind CDN 问题被修复。


十一、Hermes Agent 安装与 OAuth 登录

Hermes Agent 是 Nous Research 开发的自学习 AI Agent,内置 OAuth 登录,无需任何第三方补丁。

11.1 一键安装(含依赖)

# 安装 Node.js (LTS) —— 部分 skill 和 MCP server 需要 curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && \ sudo apt-get install -y nodejs && \ # 安装 Hermes Agent curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash && \ # 重载 shell 环境 source ~/.bashrc && \ # 验证安装 hermes version

11.2 OAuth 登录与 Provider 配置

# 交互式选择 LLM Provider + OAuth 登录(推荐首次使用) hermes model # 可选:直接添加 OAuth 凭据 hermes auth add anthropic --type oauth # Anthropic Claude OAuth hermes auth add openrouter --api-key sk-or-... # OpenRouter API Key # 查看当前凭据 hermes auth list # 完整设置向导(Provider + Terminal + Gateway + Tools 一步到位) hermes setup

11.3 启动与使用

hermes # 启动交互式 CLI hermes --continue # 恢复上次会话 hermes gateway setup # 配置 Telegram/Discord/Slack 等消息平台 hermes doctor # 诊断问题 hermes update # 更新到最新版本

11.4 支持的 OAuth Provider

Provider认证方式说明
Nous PortalOAuth订阅制,零配置
OpenAI CodexDevice Code OAuthChatGPT 账号,用 Codex 模型
AnthropicOAuth / API KeyClaude 模型,支持 Claude Code OAuth
GitHub CopilotOAuth / TokenCopilot 订阅,GPT-5.x / Claude / Gemini
OpenRouterAPI Key200+ 模型路由
Z.AI (GLM)API Key智谱 GLM 系列
Kimi / MoonshotAPI Key月之暗面模型
Custom EndpointBase URL + KeyOllama / vLLM / SGLang 等自托管

注意hermes login / hermes logout 已废弃,统一使用 hermes auth 管理凭据。


十二、CodeBuddy / CNB 环境变量

以下为 CNB 云原生开发环境中与 CodeBuddy 相关的环境变量(敏感信息已脱敏):

# ============================ # CodeBuddy / ACC (AI Coding Companion) # ============================ ACC_PRODUCT_CONFIG_V2={"endpoint":"https://api.cnb.cool/kfc60/default-dev-env/-/ai-ide","networkEnvironment":"internal","authentication":{"type":"custom-token","attributes":{"token":"6NOjc...BCB"}},"models":[{"endpoint":"https://api.cnb.cool/kfc60/default-dev-env/-/ai-ide"},{"endpoint":"https://api.cnb.cool/kfc60/default-dev-env/-/ai-ide"},{"endpoint":"https://api.cnb.cool/kfc60/default-dev-env/-/ai-ide"}],"updates":false} ACC_USER_ID=1938853994086588416@cnb ACC_USER_NICKNAME=cnb.ageYeGZgDeAA@cnb # ============================ # CNB 平台核心变量 # ============================ CNB=true CNB_API_ENDPOINT=https://api.cnb.cool CNB_BRANCH=main CNB_BRANCH_SHA=8a796291c99d213bbcff27b84b3e43dd2fb4f01f CNB_BUILD_ID=cnb-ggo-1jm8gabgb CNB_BUILD_START_TIME=2026-04-15T12:02:09.041Z CNB_BUILD_USER=cnb.ageYeGZgDeAA CNB_BUILD_USER_EMAIL=ZVf1w...vK+cnb.ageYeGZgDeAA@noreply.cnb.cool CNB_BUILD_USER_ID=1938853994086588416 CNB_BUILD_USER_NICKNAME=张 CNB_BUILD_WEB_URL=https://cnb.cool/kfc60/default-dev-env/-/build/logs/cnb-ggo-1jm8gabgb CNB_BUILD_WORKSPACE=/workspace/ CNB_COMMENT_TYPE=note CNB_COMMIT=8a796291c99d213bbcff27b84b3e43dd2fb4f01f CNB_COMMITTER=sixther CNB_COMMITTER_EMAIL=382998946@qq.com CNB_COMMIT_MESSAGE=feat: 安装 cnb-openapi-skills CNB_COMMIT_MESSAGE_TITLE=feat: 安装 cnb-openapi-skills CNB_COMMIT_SHORT=8a796291 CNB_CPUS=8 CNB_DEFAULT_BRANCH=main CNB_DOCKER_MODEL_REGISTRY=docker-model.cnb.cool CNB_DOCKER_REGISTRY=docker.cnb.cool CNB_EVENT=vscode CNB_EVENT_URL=https://cnb.cool/kfc60/default-dev-env/-/commit/8a796291c99d213bbcff27b84b3e43dd2fb4f01f CNB_FORK_FROM_REPO_SLUG=cnb/cool/default-dev-env CNB_GROUP_SLUG=kfc60 CNB_GROUP_SLUG_LOWERCASE=kfc60 CNB_HAS_LFS_FILES=false CNB_HELM_REGISTRY=helm.cnb.cool CNB_IS_CRONEVENT=false CNB_IS_NEW_BRANCH=false CNB_IS_NEW_BRANCH_WITH_UPDATE=false CNB_IS_RETRY=false CNB_IS_TAG=false CNB_MEMORY=16 CNB_PIPELINE_DOCKER_IMAGE=docker.cnb.cool/cnb/cool/default-dev-env/dockerfile-caches:fd45d231807faeac735b4592744aa5d97e9a139d CNB_PIPELINE_ID=cnb-ggo-1jm8gabgb-001 CNB_PIPELINE_KEY=pipeline-1 CNB_PIPELINE_MAX_RUN_TIME=72000000 CNB_PIPELINE_NAME=pipeline-1 CNB_PULL_REQUEST=false CNB_PULL_REQUEST_LIKE=false CNB_REPO_ID=2044385673280798720 CNB_REPO_NAME=default-dev-env CNB_REPO_NAME_LOWERCASE=default-dev-env CNB_REPO_SLUG=kfc60/default-dev-env CNB_REPO_SLUG_LOWERCASE=kfc60/default-dev-env CNB_REPO_URL_HTTPS=https://cnb.cool/kfc60/default-dev-env CNB_RUNNER_IP=10.235.16.8 CNB_TAG_IS_PRE_RELEASE=false CNB_TAG_IS_RELEASE=false CNB_TOKEN=6NOjc...BCB CNB_TOKEN_USER_NAME=cnb CNB_VSCODE_MAX_RUN_TIME=64800000 CNB_VSCODE_PROXY_URI=https://l28h9ans0e-{{port}}.cnb.run CNB_VSCODE_REMOTE_SSH_SCHEMA=vscode://vscode-remote/ssh-remote+cnb-ggo-1jm8gabgb-001.ad8a993a-190e-447a-8996-99fc30e4edbe-6gh@cnb.space/workspace/ CNB_VSCODE_WEB_URL=https://cnb.cool/kfc60/default-dev-env/-/workspace/vscode-web/cnb-ggo-1jm8gabgb-001/ CNB_WEB_ENDPOINT=https://cnb.cool CNB_WEB_HOST=cnb.cool CNB_WEB_PROTOCOL=https CNB_WELCOME_CMD=echo "Welcome to CNB" # ============================ # VSCode / Code-Server # ============================ BROWSER=/usr/lib/code-server/lib/vscode/bin/helpers/browser.sh GIT_ASKPASS=/usr/lib/code-server/lib/vscode/extensions/git/dist/askpass.sh TERM_PROGRAM=vscode VSCODE_GIT_ASKPASS_EXTRA_ARGS= VSCODE_GIT_ASKPASS_MAIN=/usr/lib/code-server/lib/vscode/extensions/git/dist/askpass-main.js VSCODE_GIT_ASKPASS_NODE=/usr/lib/code-server/lib/node VSCODE_GIT_IPC_HANDLE=/tmp/vscode-git-0fff25e5b6.sock VSCODE_INJECTION=1 VSCODE_IPC_HOOK_CLI=/tmp/vscode-ipc-1fb7988b-0604-46e6-90bf-92c20256f00d.sock VSCODE_PROXY_URI=https://l28h9ans0e-{{port}}.cnb.run/ VSCODE_PYTHON_AUTOACTIVATE_GUARD=1

说明CNB_TOKENACC_PRODUCT_CONFIG_V2 中的 token、CNB_BUILD_USER_EMAIL 等敏感字段已脱敏(保留首尾4-5位)。