AI 参与说明(Agent:Cursor):本文根据 Cloudflare 官方文档、Changelog、产品博客,以及 Context7 库
/cloudflare/cloudflare-docs整理。资料核对于 2026-09-10。Artifacts 当前是 closed beta。本地 Cloudflare skill 里的 Artifacts 参考仍可能写artifacts.cloudflare.net/v1/api与 gateway JWT;现行控制面以 Cloudflare v4 REST 为准。运行记录:模型grok-4.6,提供方xAI,执行入口 Cursor。reasoning effort 与 CLI 版本未取得运行记录。
场景补充(2026-09-11,Agent:Cursor):补充公开 GitHub 某版本归档、离线分析与 Agent 接入;钉死版本用 commit SHA 或 GitHub source archive,不走 GitHub App / Origin。运行记录:模型
grok-4.6,提供方xAI,执行入口 Cursor。reasoning effort 未取得运行记录。
结论:Artifacts 是你的 Cloudflare 账户拥有的可编程 Git 存储面,不是 GitHub / Origin 那种「某个用户或某个 installation 的 forge」。 应用代码自己创建 Namespace 与 repo、自己签发 repo-scoped token,再把 remote 交给任意 Git 客户端、Sandbox 或 Agent。官方一句话是 Versioned storage that speaks Git。适合 Lovable 式每用户 / 每会话仓;不适合替代团队主仓库上的 Pull Request、评审与安装级权限。Artifacts overview
Artifacts stores versioned file trees behind a Git-compatible interface. Create repositories programmatically, import existing repositories, and hand off a URL to any standard Git client. Artifacts overview
与 GitHub API、Cursor Origin API 的对照,以及何时毕业到 forge,见 Cursor Origin 与 Cloudflare Artifacts:代码协作平台与 Agent 可编程 Git 存储选型。
阅读前先看这几个词
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| Artifacts | 保留原名(产品名称) | Cloudflare 的版本化、Git 兼容文件树存储 |
| Namespace | 命名空间 | 仓库的顶层容器;按环境、租户或流量分片 |
| Repository | 仓库 | 一个隔离的 Git 服务,有独立 remote、token 与历史 |
| Control Plane | 控制面 | Workers binding / REST / Wrangler:建仓、fork、import、发 token |
| Data Plane | 数据面 | Git Smart HTTP,以及 REST / binding 的只读 content 路由 |
| Repo-scoped Token | 仓库级令牌 | 只对单个仓有效的 Git 凭证,格式 art_v1_<40 hex>?expires=<unix> |
| Workers binding | Workers 绑定 | 通过 env.ARTIFACTS 调控制面,Worker 代码里不传 API Token |
| Git Smart HTTP | Git Smart HTTP | 经 HTTPS 上的 git-upload-pack / git-receive-pack 交换对象 |
| Fork | 派生 | 从已有仓复制历史,生成独立新仓、独立 token |
| Import | 导入 | 从公开 HTTPS Git remote 拉进 Artifacts |
| ArtifactFS | 保留原名 | blobless clone + FUSE 按需 hydrate;可用于任意 Git remote |
| Event subscription | 事件订阅 | 把仓生命周期事件送到 Worker / Queue / Workflow |
| Jurisdiction | 司法管辖 | 创建 Namespace 时可选 eu 或 us,之后不可改 |
它解决什么问题
GitHub、GitLab、Cursor Origin 面向人与团队:组织、安装、Pull Request、评审、检查。它们的 API 主语是某个用户、某个 org,或装进客户工作区的 App。你可以做 Code Review SaaS,但仓仍归客户所有。
Artifacts 面向 Agent 与自动化:Create a thousand, a million or ten million repos: one for every agent, for every upstream branch, or every user. 官方最佳实践写得更硬:If you have 10,000 agents, create 10,000 repos. Artifacts now in beta Best practices
适合用 Artifacts 的时候:
- 要存的是版本化文件树,而不是单个 R2 对象、KV 键或 SQL 行
- 需要把工作交给会 Git 的 Agent、Sandbox、CI
- 每个用户、会话、任务要隔离历史、清理和访问控制
- 从共享基线 fork,再 diff / merge 结果
不适合单独承担:
- 团队主仓库的长期评审、CODEOWNERS、安装级权限
- 私有 GitHub / Origin 仓的 OAuth 与细粒度授权(仍走 GitHub App / Origin App)
- 把开源社区协作直接建在 closed beta 存储层上
flowchart TB
ask["需要存版本化文件树?"] --> q1{"仓归谁所有?"}
q1 -->|客户的 GitHub / Origin 工作区| forge["客人进入客户的 forge"]
q1 -->|你的 Cloudflare 账户| art["Artifacts"]
art --> ns["Namespace"]
ns --> repo["每用户 / 每会话 / 每 Agent 一个 Repository"]
repo --> git["Git Smart HTTP"]
repo --> rest["REST content 只读"]
forge --> gh["GitHub App / Origin App"]
核心概念
Namespace
A namespace is the top-level container for repositories. Use it to separate environments, tenants, or shards. Repository names are unique within a namespace, not across the account. You can have app in both prod and staging. Namespaces
你可以显式 POST /artifacts/namespaces,也可以在还不存在的名字下创建第一个 repo,让平台隐式建 Namespace。需要把数据限制在 eu 或 us 时,必须在创建时带 jurisdiction;创建后不可改。Data localization
命名规则与 repo 相同:以字母或数字开头,后续可用字母、数字、.、_、-。
Wrangler binding、REST base URL、Git remote 必须使用同一个 Namespace 名。
Repository
Each repo is an isolated Git service with its own remote URL, tokens, and durable state. Like Durable Objects, a repo is a single logical instance that Cloudflare can route to from any region. How Artifacts works
同一仓有三套接口,指向同一份数据:
| Interface | 用途 | 返回 |
|---|---|---|
| Workers binding | Worker 里建仓、import、fork、发 token、读 log / commit / tree | 元数据、repo handle、token |
| REST API | 外部系统做同样的控制面,外加 content 只读 | v4 envelope,或文件字节 |
| Git protocol | clone / fetch / pull / push | 标准 Git 行为 |
The Workers binding and the REST API are control-plane interfaces. The Git protocol is the data-plane interface. Binding 可以建仓,但不能在仓里写文件;写入走 Git(本地 git、Sandbox 里的 git,或 Worker 里的 isomorphic-git)。Repositories isomorphic-git example
常见顺序:
- binding 或 REST 建仓 / import / fork
- 记下
remote - 签发 repo-scoped token
- 用
remote+ token 做 Git 读写
Token
Artifacts tokens are repo-scoped. A token minted for one repository does not grant access to another repository, even in the same namespace.
| Scope | 允许 |
|---|---|
read | git clone、git fetch、git pull |
write | 上述全部,外加 git push |
格式:art_v1_<40 hex>?expires=<unix_seconds>。create / import / fork 返回 token 字符串,过期写在 ?expires=。createToken / POST /tokens 额外返回 expiresAt / expires_at。REST 的 ttl:最短 60 秒,最长 31,536,000 秒(约一年),默认 86,400 秒。默认 scope 是 write。
三类凭证不要混:
| 平面 | 凭证 | 权限 |
|---|---|---|
| Workers binding | Wrangler 里的 artifacts binding | 部署后的 Worker 直接调 env.ARTIFACTS |
| REST | Cloudflare API Token(Artifacts Read / Edit) | 控制面 HTTP |
| Git | Repo-scoped Token | 只对该仓的 Smart HTTP |
Cloudflare API tokens authenticate control-plane access. Repo-scoped Artifacts tokens authenticate Git access. Authentication
它怎么工作
flowchart TB
subgraph control [Control Plane]
W[Worker env.ARTIFACTS]
API[Cloudflare v4 REST]
CLI[wrangler artifacts]
Dash[Dashboard]
end
subgraph store [Account-owned storage]
NS[Namespace]
R[Repository / Durable Object]
NS --> R
end
subgraph data [Data Plane]
Git[Git Smart HTTP]
Content[REST /file /log /tree]
IFS[isomorphic-git in Worker]
SB[Sandbox git]
end
W --> NS
API --> NS
CLI --> NS
Dash --> NS
R --> Git
R --> Content
IFS --> Git
SB --> Git
Durability is the default. Cloudflare replicates repo data synchronously across multiple data centers and copies it asynchronously to object storage and snapshots. You do not build your own replication pipeline. How Artifacts works
官方博客(实现细节,不是 SLA):每个 repo 是 Durable Object;Git server 用 Zig 写成约 100KB WASM;对象落 SQLite,超过行大小限制则分块;大对象可 snapshot 到 R2;token 跟踪可用 KV。Artifacts: versioned storage that speaks Git
Git remote 形态:
https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/<namespace>/<repo>.git
以 create / get 返回的 remote 为准,不要手拼 changelog 里的旧 URL。2026-04-16 changelog 出现过 https://artifacts.cloudflare.net/v1/api/... 与不含 account 前缀的 clone URL;现行 REST 文档更新于 2026-08-13,控制面走 https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/artifacts/...。REST API Git protocol
协议能力:clone / fetch 支持 Git protocol v1 与 v2;push 只支持 v1 receive-pack。部分可选 v1 capability(如 filter、include-tag)未支持。
产品入口
| 入口 | 做什么 | 什么时候用 |
|---|---|---|
| Dashboard | 看 Namespace / repo / 文件,复制 remote,签发 token | 人工排查;路径是 Storage & Databases → Artifacts |
| Wrangler | `wrangler artifacts namespaces | repos …` |
| Workers binding | 应用运行时建仓、fork、发 token | SaaS 热路径 |
| REST | 非 Worker 后端、导入公开仓、读文件字节 | 外部系统 |
| Git | 真正读写历史 | Agent、Sandbox、开发机 |
| Events | cf.artifacts.repo.* | 建仓后处理、push 后 CI |
| ArtifactFS | 大仓快速挂载 | Sandbox / VM 启动时间敏感 |
Dashboard 管理于 2026-06-17 进入文档。未开通 beta 时先填 申请表。Manage Artifacts from the Cloudflare dashboard
怎么用:从零到第一仓
前置:Workers Paid 账户、Artifacts closed beta 已开通、Cloudflare API Token 具备 Artifacts Edit(REST)或已 wrangler login(binding / CLI)。
1. 选定 Namespace
学习阶段用 default。生产按环境拆:staging / prod。需要数据驻留时显式创建:
export ACCOUNT_ID="<YOUR_ACCOUNT_ID>"
export CLOUDFLARE_API_TOKEN="<YOUR_API_TOKEN>"
export ARTIFACTS_ACCOUNT_BASE_URL="https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/artifacts"
curl --request POST "$ARTIFACTS_ACCOUNT_BASE_URL/namespaces" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"namespace": "prod",
"jurisdiction": "us"
}'
2. Worker 绑定
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "artifacts-worker",
"main": "src/index.ts",
"compatibility_date": "2026-09-10",
"artifacts": [
{
"binding": "ARTIFACTS",
"namespace": "prod"
}
]
}
artifacts 在 named Wrangler environment 里不可继承,每个环境都要重复声明。本地 wrangler dev 可加 remote = true 打到远端 Artifacts。然后 npx wrangler types,把生成的 Artifacts 类型当 source of truth。Workers binding
3. 创建并交给 Git 客户端
interface Env {
ARTIFACTS: Artifacts;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// 生产环境必须先鉴权调用方,再建仓或返回 token。
const created = await env.ARTIFACTS.create("starter-repo", {
description: "Repository for automation experiments",
readOnly: false,
setDefaultBranch: "main",
});
return Response.json({
name: created.name,
remote: created.remote,
token: created.token,
});
},
} satisfies ExportedHandler<Env>;
开发机克隆(推荐把完整 token 放在 header,不要写进 URL):
export ARTIFACTS_REMOTE="<PASTE_REMOTE_FROM_CREATE>"
export ARTIFACTS_TOKEN="<PASTE_TOKEN_STRING>"
git -c http.extraHeader="Authorization: Bearer $ARTIFACTS_TOKEN" \
clone "$ARTIFACTS_REMOTE" artifacts-clone
短时一次性命令才把 secret 放进 Basic auth 密码位;用户名任意非空即可,常用 x。先去掉 ?expires=:
export ARTIFACTS_TOKEN_SECRET="${ARTIFACTS_TOKEN%%\?expires=*}"
export ARTIFACTS_AUTH_REMOTE="https://x:${ARTIFACTS_TOKEN_SECRET}@${ARTIFACTS_REMOTE#https://}"
git clone "$ARTIFACTS_AUTH_REMOTE" artifacts-clone
4. 从公开 Git remote 导入
const imported = await env.ARTIFACTS.import({
source: {
url: "https://github.com/cloudflare/workers-sdk",
branch: "main",
depth: 100,
},
target: { name: "workers-sdk" },
});
REST 等价路径是 POST .../repos/:name/import,body 为 { url, branch?, depth?, read_only? }。url 必须是完整 HTTPS Git remote。仓仍在 importing / forking 时可能 409,按错误信息重试。Import repositories
私有 GitHub 仓的授权不在 Artifacts 控制面里;导入文档面向公开 HTTPS remote。官方把 branch 写成 Branch to import,没有承诺 tag 或 commit SHA 可作为该字段。要钉死某个版本,用下面的归档场景,不要把 tag 名塞进未文档化的 branch。
API 速查
Workers binding:Namespace 方法
| Method | 作用 |
|---|---|
create(name, opts?) | 建仓;返回 name / remote / defaultBranch / 初始 token 字符串 |
get(name) | 已存在且 ready 的 handle;未就绪抛错 |
list({ limit, cursor }) | 分页;status 为 ready / importing / forking |
import({ source, target }) | 从公开 HTTPS remote 导入 |
delete(name) | 删除 |
opts:readOnly、description、setDefaultBranch。
Workers binding:repo handle
先 await env.ARTIFACTS.get(name)。
| Method | 作用 |
|---|---|
createToken(scope?, ttl?) | 默认 scope write;返回 { plaintext, expiresAt } |
listTokens() / revokeToken(tokenOrId) | 审计与吊销 |
fork(name, opts?) | description / readOnly / defaultBranchOnly |
log({ ref, limit, offset }) | commit 历史 |
readCommit(hash) / readTree(hash) | 按 SHA-1 读对象 |
没有 writeFile。Worker 内写入用 isomorphic-git 官方示例(MemoryFS + git.push,onAuth 的 password 是去掉 ?expires= 的 secret)。
REST:账户级 Namespace
Base:https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/artifacts
| Method | Path |
|---|---|
POST | /namespaces body { namespace, jurisdiction? } |
GET | /namespaces?limit=&cursor= |
GET | /namespaces/:namespace |
REST:Namespace 内 repo 与 token
Base:.../artifacts/namespaces/$ARTIFACTS_NAMESPACE
| Method | Path | 说明 |
|---|---|---|
POST | /repos | { name, description?, default_branch?, read_only? } |
GET | /repos | limit 默认 50、最大 200;search / sort / direction / cursor |
GET | /repos/:name | 元数据 + remote |
DELETE | /repos/:name | 202 Accepted |
POST | /repos/:name/fork | { name, description?, read_only?, default_branch_only? } |
POST | /repos/:name/import | { url, branch?, depth?, read_only? } |
GET | /repos/:name/log | ref / limit / offset |
GET | /repos/:name/commit/:hash | JSON |
GET | /repos/:name/tree/:hash | JSON |
GET | /repos/:name/blob/:hash | 原始 blob 字节 |
GET | /repos/:name/file?ref=&path= | application/octet-stream |
GET | /repos/:name/raw/:ref/:path | 嗅探 Content-Type |
GET | /repos/:name/tokens | state:active / expired / revoked / all |
POST | /tokens | { repo, scope?, ttl? },返回 plaintext + expires_at |
DELETE | /tokens/:id | 吊销 |
Successful blob, file, and raw responses return file bytes directly instead of JSON. 错误仍走 v4 envelope。这些 content 路由用 Cloudflare API Token,不是 Git token。REST API
Wrangler
npx wrangler artifacts namespaces list
npx wrangler artifacts namespaces get default
npx wrangler artifacts repos create starter-repo --namespace default
npx wrangler artifacts repos list --namespace default
npx wrangler artifacts repos get starter-repo --namespace default
npx wrangler artifacts repos issue-token starter-repo --namespace default --scope read --ttl 3600
npx wrangler artifacts repos delete starter-repo --namespace default
最佳实践
下面先复述官方规则,再给出可执行场景。官方原文:Best practices。
官方规则(必须对齐)
- 一单位工作一仓。Create one repo for each unit of autonomous work. If you have 10,000 agents, create 10,000 repos. 不要用一个共享仓当多个 Agent 的队列。只有协作者共享同一生命周期时才用 branch。
- 名字带稳定 ID。仓名在 Namespace 内唯一。用
${agentName}-${sessionId}-${repoName},不要所有人抢docs-site。 - 从已审查基线 fork。比手工往每个新仓拷模板更安全,下游 diff 也更短。
- 最小权限、短时 token。检索 / 审查用
read;只有必须 push 的会话才发write。每次会话重新签发,不要给所有 Agent 同一张长期 write token。 - 提示词进 git notes。
git notes挂在 commit 上,不改 working tree。跨系统同步时记得 push / fetchrefs/notes/*。 - 用 Namespace 切环境与限流。控制面限额是每个 Namespace 2,000 请求 / 10 秒。热路径拆
agents-batch/agents-realtime,不要把所有仓堆进default。
场景:Lovable 式租户工作区
目标:SaaS 给每个登录用户一份可 fork 的应用仓,Agent 在仓里改代码并 push,平台在 push 后跑检查。
本文建议(不是官方硬性 API):租户身份放在你自己的鉴权层(Clerk 等);Artifacts 只存文件树。仓名不要用邮箱原文,用你系统里的稳定 tenantId。
| 步骤 | 操作 | 预期产物 | 通过标准 |
|---|---|---|---|
| 1 | 创建 prod Namespace(需要驻留则带 jurisdiction) | GET /namespaces/prod 成功 | 名称与 Wrangler binding 一致 |
| 2 | 人工审查后维护 starter-app 基线仓 | status: ready,read_only: true 可选 | 基线只有平台角色能 push |
| 3 | 用户首次进入:从基线 fork("app-${tenantId}") | 新仓 remote + 初始 token | 仓名可预测;重复进入走 get 而不是再 fork |
| 4 | 会话开始:createToken("write", 3600),写入 Sandbox ARTIFACTS_GIT_REMOTE | 1 小时 write token | 调用方已通过应用鉴权;token 不进日志 |
| 5 | Agent git clone → 改文件 → commit → push | last_push_at 更新 | read token 不能 push |
| 6 | 订阅 cf.artifacts.repo.pushed,省略 repoName 以覆盖 Namespace 内所有仓 | Workflow 实例启动 | 一次 CI 定义服务全部租户仓 |
| 7 | 会话结束:revokeToken;用户删除应用:delete(name) | token revoked;仓删除 202 | 存储计费在显式删除后停止增长 |
Worker 侧 fork 与发牌(示意,须先鉴权):
interface Env {
ARTIFACTS: Artifacts;
}
async function openTenantWorkspace(
env: Env,
tenantId: string,
workspaceAlreadyExists: boolean,
) {
const name = `app-${tenantId}`;
if (workspaceAlreadyExists) {
const repo = await env.ARTIFACTS.get(name);
return {
name,
remote: repo.remote,
token: (await repo.createToken("write", 3600)).plaintext,
};
}
const baseline = await env.ARTIFACTS.get("starter-app");
const forked = await baseline.fork(name, {
description: `Workspace for ${tenantId}`,
defaultBranchOnly: true,
readOnly: false,
});
return {
name: forked.name,
remote: forked.remote,
token: forked.token,
};
}
get() 在仓不存在或尚未 ready 时会抛错。官方 Sandbox 示例要求:用应用侧记录判断「刚创建还是复用」,直接按 ID 查找,不要扫 list(),也不要用宽泛 catch 把缺仓、鉴权和校验失败吞成同一种重试。Sandbox SDK + Artifacts
repo.remote 与 createToken() 的返回形状以 npx wrangler types 生成文件为准。
条件变化时:
- 只要索引、不要改代码:步骤 4 改
createToken("read", 900)。 - 控制面打满 2,000 / 10s:按租户哈希把新仓分到
prod-a/prod-bNamespace。 - 需要团队评审或对外开源:把仓毕业到 GitHub / Origin,而不是在 Artifacts 上模拟 forge。
场景:归档公开 GitHub 的某个版本,再做离线 / Agent 分析
目标:把某个开源仓的 一个确定版本 存下来,本机离线读,或交给 Agent。公开仓不需要 GitHub App,也不需要 Origin。GitHub App / Origin App 是给私有仓授权、webhook 和回写 PR / check 用的。
分析记录绑定 owner/repo@commitSha,不要用 branch 名或浮动 tag 当 ID。GitHub 说明:An archive of a commit ID will always have the same file contents;tag 和 branch 可以移动。可复现归档用 40 位 commit SHA。Downloading source code archives
flowchart TB
pub["公开 GitHub HTTPS?"] --> yes{"只要这一版的文件树?"}
yes -->|是,一次性离线| gh["git clone --branch TAG 或 GitHub archive URL"]
yes -->|要长期给 Agent 复用| art["Artifacts import 公开 remote"]
art --> pin["status ready 后 checkout 目标 SHA,read_only"]
pub --> no["私有仓才需要 GitHub App / PAT"]
| 需求 | 方案 | 不要用 |
|---|---|---|
| 本机离线读一版 | git clone + checkout SHA,或下载 GitHub source archive | Origin、GitHub App |
| Agent 多次分析、可 fork 任务仓 | Artifacts import 公开 HTTPS,再 checkout SHA | 把 Origin 当镜像盘 |
| 只要 tar,不要 Git 历史 | GitHub archive URL 或 REST tarball/{ref},需要持久化再放 R2 | 为读公开树去装 App |
| 私有仓、要写回 PR | GitHub App / Origin App | Artifacts import |
路径 1(官方 Git,零 Cloudflare)
# 先把 tag 解析成 SHA,再按 SHA 克隆,避免 tag 被移动
git ls-remote --tags https://github.com/facebook/react.git 'v18.3.1^{}'
git clone --filter=blob:none --no-checkout \
https://github.com/facebook/react.git react-v18.3.1
git -C react-v18.3.1 fetch --depth 1 origin <COMMIT_SHA>
git -C react-v18.3.1 checkout --detach <COMMIT_SHA>
只要工作树、不要历史时,GitHub 直接提供 source archive(公开仓匿名可下):
# tag 快照(tag 可能被移动,不适合当长期 ID)
curl -L -o react-v18.3.1.tar.gz \
https://github.com/facebook/react/archive/refs/tags/v18.3.1.tar.gz
# commit 快照(可复现)
curl -L -o react-<COMMIT_SHA>.tar.gz \
https://github.com/facebook/react/archive/<COMMIT_SHA>.tar.gz
路径 2(要给 Agent 一个可 fork 的真源:Artifacts)
这是官方 import 的用途:a baseline repo that agents fork from。本文建议把导入结果当成冻结基线,而不是继续跟踪上游 main。
| 步骤 | 操作 | 预期产物 | 通过标准 |
|---|---|---|---|
| 1 | 解析目标版本的 commit SHA(git ls-remote 或 GitHub UI) | 40 位 SHA | 分析 ID 使用该 SHA |
| 2 | import 含该 commit 的 branch(通常是 main);depth 要够深,否则旧版本不在浅历史里 | status: ready | GET .../commit/:sha 成功 |
| 3 | read_only: true(REST)或 fork 出只读任务仓 | 基线不可被 Agent push 污染 | write token 无法改基线 |
| 4 | Agent:GET /file?ref=<SHA>&path=...,或 createToken("read") 后 git clone 再 checkout --detach <SHA> | 工作树等于该 commit | 文件内容与 GitHub archive 一致 |
| 5 | 多轮分析另 fork 任务仓;结束 delete | 基线仍在 | 任务仓删除后基线 GET 仍 200 |
const imported = await env.ARTIFACTS.import({
source: {
url: "https://github.com/facebook/react",
branch: "main",
},
target: {
name: "archive-react-18-3-1",
opts: { readOnly: true },
},
});
导入返回后仍可能 409。list() 里 status 为 ready,并且 GET .../repos/archive-react-18-3-1/commit/<COMMIT_SHA> 成功,才算这版进了 Artifacts。浅克隆 depth: 100 很可能不含两年以前的 release;归档旧版本时不要设很小的 depth,或改走路径 1 的 archive URL。
Sandbox / 本机 Agent 也可以 直接 git clone https://github.com/owner/repo.git,公开 HTTPS 不需要 token。容器不是持久盘:分析要复现,把 checkout 后的树或 tarball 放到 Artifacts / R2,而不是留在 Sandbox 磁盘。大仓启动慢时,ArtifactFS 可以对 GitHub remote 做 blobless clone,不限于 Artifacts。ArtifactFS
本文建议不要走 Origin 的原因:公开仓没有「安装到客户工作区」这件事。Origin Partner API 不能按 namespace 自助开仓,mirror 还受 GitHub inbound 限制。为读一版开源树去装 Origin App,成本高于 import 或 GitHub archive。
条件变化时:
- 仓是私有的:才需要 PAT 或 GitHub App;Artifacts
import文档不覆盖私有 HTTPS。 - 只要 Issues / PR / Actions:仍在 GitHub 上读,Artifacts 只存文件树。
- 上游还在推:基线仓保持
read_only;新版本另一次import到新名字,例如archive-react-<shortSha>,不要在同一仓里git pull冲掉旧 SHA。
场景:Sandbox 一仓一 ID
官方模板 git-repo-per-sandbox:Sandbox ID 与 Artifacts repo 名相同;新建则 create(sandboxId),复用则 get + createToken("write", 3600);把 token secret 嵌进 URL 后写入 ARTIFACTS_GIT_REMOTE。短时 token,且只在会话已授权 push 之后注入。Sandbox SDK + Artifacts
容器不是持久盘。Sandbox 休眠后工作树会丢,跨生命周期的真源应在 Artifacts(或 R2 备份)。见 Sandbox SDK:命令、文件、进程与会话 API 实战。
场景:push 后构建并部署
cf.artifacts.repo.pushed 可触发 Workflow。官方 Wrangler 注释:If you don’t set repoName we will run the same workflow for every push on any repo in your Artifacts namespace. 这是平台 Namespace 模式:一份 CI 覆盖该 Namespace 里每一个客户仓,并可把产物部署到 Worker 或 Workers for Platforms User Worker。Build and deploy
通过标准:一次 push 产生 Workflow 实例;检查失败则不部署;部署步骤才使用收窄后的 API Token。
事件
2026-05-19 起可订阅。Event subscriptions
账户级(source artifacts):
| type | 何时 |
|---|---|
cf.artifacts.repo.created | 建仓 |
cf.artifacts.repo.deleted | 删除 |
cf.artifacts.repo.forked | fork;payload 含目标 Namespace / repo |
cf.artifacts.repo.imported | 从外部 remote 导入 |
仓级(source artifacts.repo,需 namespace + repoName):
| type | 何时 |
|---|---|
cf.artifacts.repo.pushed | push;含 ref / before / after / commits |
cf.artifacts.repo.cloned / fetched | clone / fetch |
cf.artifacts.repo.token.created / token.revoked | 发牌与吊销;created 含 tokenId / scope / expiresAt,不含 plaintext |
ArtifactFS
ArtifactFS mounts a Git repository as a local filesystem without waiting for a full clone. It starts with a blobless clone, then hydrates blobs through FUSE. 适用于大仓;小仓直接 git clone 更简单。它可用于 Artifacts remote,也可用于 GitHub / GitLab 等任意 Git remote。Agent 仍用 commit + push,没有另一套写回 API。ArtifactFS
限额、定价与 beta
整理日期 2026-09-10。overview 标注 closed beta(2026-05-05);定价页 2026-04-21;限额页 2026-05-04。
| 项目 | 限额 |
|---|---|
| 控制面请求 | 每个 Namespace 每 10 秒 2,000 |
| Git 请求 | 每个 artifact 每 10 秒 2,000 |
| 单仓存储 | 10 GB |
| 账户存储 | 1 TB(可申请提高) |
| 仓数 / Namespace 数 | 不限 |
| 计费项 | Workers Free | Workers Paid |
|---|---|---|
| Operations | 不可用 | 每月前 10,000,之后每 1,000 次 $0.15 |
| Storage | 不可用 | 每月前 1 GB-mo,之后每 GB-mo $0.50 |
Operations 包括 create、push、pull、clone 等。Storage 按账户内所有仓的 GB-mo,算法与 Durable Objects SQL storage 相同。Replicas do not add storage charges. Repos remain stored until you explicitly delete them. 博客写 Free 计划会在 beta 推进中开放;当前定价页仍标 Unavailable。Pricing
「tens of millions of repos」是产品叙事。设计应对齐限额、定价与账户开通状态,而不是把营销句当成 SLA。
和站内其它存储怎么选
| 需求 | 用 | 不要用 Artifacts 代替 |
|---|---|---|
| 单个对象、图片、数据集 | R2 | 版本化工作树 |
| 配置键、会话指针 | KV | Git 历史 |
| 关系数据 | D1 | commit graph |
| 按业务键串行协调 | Durable Objects | 把 DO 当 Git 服务器来自研 |
| 隔离 Linux 执行 | Sandbox SDK | Sandbox 磁盘当长期真源 |
| 团队评审与安装授权 | GitHub / Origin | Artifacts |
Cloudflare 平台 skill 的决策树把 versioned file trees 指向 Artifacts,把 objects / KV / SQL 留给 R2、KV、D1。这与官方 docs 一致。
关联阅读
- Cursor Origin 与 Cloudflare Artifacts:代码协作平台与 Agent 可编程 Git 存储选型:API 主语、调用链与场景分流
- Workers:运行时 API、Bindings 与执行模型:binding 与控制面 Token 的职责边界
- Sandbox SDK:命令、文件、进程与会话 API 实战:容器不是持久盘;可与 Artifacts 一 ID 一仓组合
- Durable Objects 使用方式与接口整理:Artifacts repo 背后的隔离实例模型
- Workflows:实例、步骤、事件与恢复 API 实战:
cf.artifacts.repo.pushed触发 CI
参考资料
- Artifacts(overview,closed beta,更新于 2026-05-05)
- Get started
- Namespaces(更新于 2026-08-13)
- Repositories
- How Artifacts works
- Best practices
- Authentication
- Workers binding(更新于 2026-06-11)
- REST API(现行 v4 控制面,更新于 2026-08-13)
- Git protocol
- Wrangler commands
- Import repositories
- Downloading source code archives
- Event subscriptions
- Build and deploy
- Data localization
- ArtifactFS
- isomorphic-git
- Sandbox SDK + Artifacts
- Limits
- Pricing
- Artifacts now in beta
- Event subscriptions changelog
- Dashboard management changelog
- Artifacts: versioned storage that speaks Git
Context7 核查:通过 /cloudflare/cloudflare-docs 核对了 Workers binding(含 import())、REST v4 base URL、token TTL、Git http.extraHeader、best practices 的 fork / 短时 token / Namespace 分片,以及 cf.artifacts.repo.pushed 可省略 repoName 的平台 Namespace 模式。changelog 中的 artifacts.cloudflare.net/v1/api 只作历史线索。