cloudflare-os

应用程序

cloudflare/cloudflare-os

基于Cloudflare的AI智能体工作空间。

项目简介

Cloudflare OS 是一个 AI 生产力环境,提供聊天界面、沙盒应用开发与 Gatekeepers 安全框架。用户可通过 AI 代理创建文档和定制小应用,每个应用运行在私有沙盒实例中,并支持人工审批操作。

README 预览

# Cloudflare OS: An AI productivity environment\n\nCloudflare OS is an "operating system" for AI productivity originally developed for use inside Cloudflare. A large portion of Cloudflare's workforce -- from engineering to sales and everything in between -- uses Cloudflare OS every day to help them do their jobs.\n\n\n\nThis is not a traditional computer operating system. We use the term "operating system" in two senses:\n\n* An operating system for *the company* to be productive with AI, in a way that is safe, so that the security team can sleep at night.\n* An operating system for AI workloads, analogous to the sense in which a traditional operating system manages compute workloads.\n\nCloudflare OS provides three things in particular:\n\n1. An agent chat UI where you can ask agents to do tasks, preloaded with knowledge about how your company operates.\n2. Sandboxed application development, so that you can ask agents to build "gadgets" (small personal apps) and safely share what you've built with others.\n3. A security framework, called Gatekeepers, that applies guardrails to both agents and apps such that non-technical users can safely "go nuts" and nothing bad will happen.\n\nWe are making Cloudflare OS open source so that others can copy it and customize it for their own company. The idea is not that your company uses Cloudflare OS, but rather that you make it "*Your Company* OS".\n\n## Quick Start\n\nTo quickly run Cloudflare OS locally, [install pnpm](https://pnpm.io/), then do:\n\n    pnpm run-local\n\nThen visit: http://localhost:8787\n\nThis runs the whole stack locally on wrangler and workerd. This is not meant for production use, but is a quick way to see what the product does.\n\nAlternatively, you can [deploy to your Cloudflare account](https://os.cloudflare.app/deploy).\n\n(More options at the end of this readme.)\n\n### What to try\n\nTry prompts like:\n\n* "Make slides for my upcoming meeting with a customer." (This will use the built-in slides blue

常见问题 (5)

故障排除
如何修复 GitHub gatekeeper 连接在建立连接后恰好 8 小时出现 "Bad credentials" 错误而失败的问题?

这会影响新的 GitHub OAuth 应用,因为 GitHub 现在签发的访问令牌会在 8 小时后过期,并同时提供刷新令牌。旧版本的 gatekeeper-github 仅存储访问令牌而丢弃了 refresh_token,导致令牌过期后调用失败。

临时解决方法:
1. 在 GitHub 中,前往 **Settings → Developer settings → OAuth Apps → 选择你的应用 → Optional features**。
2. 选择停用 **expiring user tokens**。
3. 让每位受影响的用户先 **Disconnect**,然后再 **Connect** 一次他们的 GitHub 账户。在停用之前签发的令牌仍会过期。

永久修复方案:将 gatekeeper-github 升级到包含 issue #641 修复的版本。该修复会持久化保存 refresh_token 及令牌过期时间,在过期前使用 POST https://github.com/login/oauth/access_token 并携带 grant_type=refresh_token 进行刷新,原子性地存储 GitHub 轮换后的令牌对,对并发刷新进行序列化处理,并在 GitHub 返回 bad_refresh_token 时提示重新连接。不包含 expires_in 的 OAuth 应用保留之前令牌不过期的行为。

来源 Issue #641
故障排除
在 Windows 上运行 workshop-frontend build 或 pnpm lint 时,如何修复“Failed to find executable rm”错误?

Vite+ 的 clean:dist 任务直接调用了仅限 POSIX 的 rm 二进制文件,因此 Windows 无法找到它。在 packages/workshop-frontend/vite.config.ts 中,将 command: 'rm -rf dist' 替换为 Node 内置的文件系统删除方式:

'clean:dist': {
  command: `node -e "require('node:fs').rmSync('dist', { recursive: true, force: true })"`,
  cache: false,
}

或者,更新到包含 PR #373(c0ccaa1)的修订版本,该版本使用了 fs.rmSync(..., { recursive: true, force: true })。然后重新运行 pnpm exec vp run -F @gadgets/workshop-frontend --no-cache build 或 pnpm lint。

来源 Issue #250
故障排除
如何修复 Windows 上 bundled blueprint 测试失败的问题:预期路径使用 '/',而实际路径使用 '\'?

实现是正确的;测试硬编码了 POSIX 路径分隔符。在 Windows 上,Node 的 readlinkSync() 和 path.relative() 返回以反斜杠分隔的路径。修复 scripts/build-bundled-blueprints.test.ts,使断言能够感知平台差异:将符号链接目标与 path.normalize("../NOTES.md") 进行比较,并将错误消息的正则表达式改为可匹配任一种分隔符,例如 /ignored by Git: example[\\/]files[\\/]dist[\\/]client\.js/ 和 /ignored by Git: example[\\/]blueprint\.json/。然后运行 pnpm --filter @gadgets/scripts test。这就是 PR #653 中的修复,已在 Windows 11 和 Ubuntu/WSL 上使用 Node 24.18.0 验证通过。作为临时解决方案,可以在 WSL 下运行测试。单独的 gatekeeper-google 失败与此无关,是由 Git for Windows 在 core.symlinks=false 时将符号链接检出为普通文件导致的。

来源 Issue #652
故障排除
为什么即使 refresh token 仍然有效,Confluence gatekeeper 也会在一小时后显示 "Credentials expired"?

Confluence gatekeeper 将短期有效的 Atlassian 访问令牌的一小时过期时间记录为整体凭据的过期时间。在此之后,即使 getAccessToken() 可以透明地使用轮换刷新令牌,UI 仍会将账户标记为已过期。要解决此问题,请编辑 packages/gatekeeper-confluence/src/confluence.ts,并从 callback.complete()、callback.reconnectComplete() 和 callback.credentialsRestored() 中移除 expiresAt/new Date(grant.expiresAt) 参数。依赖正常的刷新路径,以及仅在刷新实际失败时才发送的显式 credentialsExpired() 信号。在修复之前,使用现有的 Confluence 绑定会触发刷新并暂时清除过期状态;重新连接也有效,但该消息会在一小时后再次出现。

来源 Issue #507
故障排除
如何修复在连接版本低于 15.0 的自托管 GitLab 时出现的 "GitLab OAuth token response was incomplete" 错误?

这种情况发生在 15.0 之前的自托管 GitLab 版本中,例如 GitLab 13.3,因为不过期的 OAuth 令牌会省略 expires_in 字段。GitLab gatekeeper 不得将该字段视为必填项。

修复令牌交换处理逻辑,使 expires_in 成为可选项;当该字段缺失时,将 expiresAt 留空/设为 undefined,credentials kit 会将其视为永远不需要刷新的令牌:

if (typeof tokenResponse.expires_in === "number") {
  credentials.expiresAt = new Date(
    Date.now() + tokenResponse.expires_in * 1000
  ).toISOString();
} else {
  credentials.expiresAt = undefined; // GitLab < 15.0: token does not expire
}

只有 access_token 应为必填项。重新构建并重新部署 Cloudflare OS,如有必要,删除失败的 GitLab 连接,然后通过 OAuth 重新连接。或者,将 GitLab 升级到 15.0 或更高版本,或使用包含上述修复的版本。

来源 Issue #704