How to Use Artifacts with Cloudflare Artifacts Binding for Session-Scoped Repositories

Initialize a session-scoped Artifacts client by calling createArtifact(env.ARTIFACTS, sessionId), then pass it to a Workspace or invoke its typed methods directly—all repository names remain local (unprefixed) while the binding handles namespace isolation automatically.

The Cloudflare Computer SDK provides a built-in Artifacts feature that wraps the Cloudflare Artifacts namespace binding with automatic session-scoping. This lets multiple concurrent agents share a single namespace without collisions, using a façade that prefixes repository names internally and exposes clean, local names to your code. This guide walks through the architecture, setup, and practical usage based on the actual implementation in cloudflare/computer.

Architecture: How Session-Scoped Artifacts Work

The Three Layers

The system separates concerns across three layers:

Layer File Responsibility
Binding Runtime-provided Cloudflare Artifacts namespace (env.ARTIFACTS) with raw operations
Façade packages/computer/src/artifacts/client.ts createArtifact(binding, sessionId) builds a session-scoped ArtifactClient
Workspace packages/computer/src/workspace.ts Stores the client as #artifacts, exposes via ws.artifacts getter

Session-Scoping Mechanism

When you create a client with createArtifact(env.ARTIFACTS, sessionId), the SDK:

  1. Prefixes every repository name with ${sessionId}__ before sending to the binding
  2. Strips the prefix from returned names so your code sees only local names like "logs" rather than "agent-42__logs"

This isolation happens transparently in [client.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/src/artifacts/client.ts), letting you reason about repositories as if each session owns its own namespace.

Error Handling

Invalid inputs throw specific error types defined in [packages/computer/src/artifacts/errors.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/src/artifacts/errors.ts):

  • InvalidSessionIdError — malformed or empty session ID
  • InvalidRepoNameError — repository name violates naming rules

Setting Up the Artifacts Binding

1. Configure wrangler.toml

Declare the namespace binding in your Worker configuration:

[[bindings.artifacts]]
name = "ARTIFACTS"
namespace_id = "your-namespace-id-here"

2. Create the Session-Scoped Client

In your Worker, construct the client once per session:

import { Workspace } from "@cloudflare/computer";
import { createArtifact } from "@cloudflare/computer/artifacts";

declare const env: {
  ARTIFACTS: Bindings["ARTIFACTS"]; // Cloudflare Artifacts namespace binding
};

const sessionId = "agent-42"; // Typically the worker-agent ID
const artifacts = createArtifact(env.ARTIFACTS, sessionId);

The createArtifact factory function is implemented in [packages/computer/src/artifacts/client.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/src/artifacts/client.ts).

3. Integrate with Workspace

Pass the client to a Workspace so downstream code can access it:

const ws = new Workspace({
  sessionId,
  artifacts: { binding: env.ARTIFACTS, sessionId },
});

// ws.artifacts === artifacts (same client instance)
await ws.artifacts.create("build-cache", {
  description: "CI cache for this agent",
});

The workspace stores this as a private #artifacts field and exposes it through an artifacts getter, per [packages/computer/src/workspace.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts).

Using the Typed Artifacts API

The ArtifactClient provides methods for repository lifecycle management. All accept local repository names—the session prefix is applied automatically.

Creating and Listing Repositories

// Create a repo scoped to this session
const repo = await ws.artifacts.create("logs", {
  description: "Per-run log storage",
  readOnly: false,
});

// List shows only this session's repositories
const repos = await ws.artifacts.list();
// → [{ name: "logs", description: "Per-run log storage", ... }]

Token Generation

Generate short-lived Git credentials:

const token = await ws.artifacts.createToken("logs", "write", 3600);
// token: { username: "...", password: "...", expiresAt: ... }

Importing External Repositories

Pin external code into your session namespace:

await ws.artifacts.import(
  "external-code",
  {
    url: "https://github.com/example/repo.git",
    branch: "main",
    depth: 1,
  },
  {
    description: "Pinned upstream snapshot",
    readOnly: true,
  }
);

These methods are documented in [docs/15_artifacts_interface.md](https://github.com/cloudflare/computer/blob/main/docs/15_artifacts_interface.md#typed-surface).

Using the CLI Inside computerd Shells

The worker-shell backend exposes an artifacts command that forwards to the same client. The implementation lives in [packages/computer/src/backends/worker-shell/artifacts-command.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/src/backends/worker-shell/artifacts-command.ts).

Available Commands


# Inside a computerd interactive shell

> artifacts repo create cache --description "CI cache"
Repo created: cache (remote https://acct.artifacts.cloudflare.net/git/agent-42__cache.git)

> artifacts repo list
cache

> artifacts token create logs --permission write --ttl 3600

The CLI handler calls ArtifactClient.cli from [packages/computer/src/artifacts/cli.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/src/artifacts/cli.ts), which dispatches argv to the appropriate typed method.

Testing with the Fake Artifacts Binding

Unit tests use FakeArtifactsBinding to simulate the Cloudflare Artifacts service without network calls:

import { FakeArtifactsBinding } from "@cloudflare/computer/tests/utilities/fake-artifacts-binding";
import { createArtifact } from "@cloudflare/computer/artifacts";

const fakeBinding = new FakeArtifactsBinding();
const client = createArtifact(fakeBinding, "test-session");

// Identical API to production
await client.create("tmp");
const list = await client.list(); // → [{ name: "tmp", ... }]

The fake binding is implemented in [packages/computer/tests/utilities/fake-artifacts-binding.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/tests/utilities/fake-artifacts-binding.ts) and mirrors all production behaviors including session prefixing.

Key Implementation Files

File Purpose
docs/15_artifacts_interface.md Design documentation, session-scoping rules, method reference
packages/computer/src/artifacts/client.ts createArtifact factory, ArtifactClient class
packages/computer/src/artifacts/cli.ts Argv-to-client dispatcher
packages/computer/src/artifacts/errors.ts InvalidSessionIdError, InvalidRepoNameError
packages/computer/src/workspace.ts Workspace integration (ws.artifacts)
packages/computer/src/backends/worker-shell/artifacts-command.ts Shell command implementation
packages/computer/tests/utilities/fake-artifacts-binding.ts In-memory test mock

Summary

Frequently Asked Questions

What happens if two sessions use the same repository name?

Each session's repositories are isolated by the ${sessionId}__ prefix applied by the façade. Two agents can both create a repo named "cache" without conflict—the binding stores them as agent-42__cache and agent-99__cache respectively, while each client sees only "cache".

Do I need to manually add the session prefix to repository names?

No. The ArtifactClient handles prefixing transparently. Always use local names like "logs" or "build-cache" in your code. The prefix is stripped from returned names and added to outgoing requests automatically.

Can I use the Artifacts API outside of a Workspace?

Yes. createArtifact(env.ARTIFACTS, sessionId) returns a standalone client you can use directly. The Workspace class simply provides convenient storage and access—it's not required for core functionality.

How do I handle errors from the Artifacts binding?

Catch InvalidSessionIdError or InvalidRepoNameError from [packages/computer/src/artifacts/errors.ts](https://github.com/cloudflare/computer/blob/main/packages/computer/src/artifacts/errors.ts). These are thrown synchronously during validation before any network calls. Binding-level errors (network, permissions) propagate as standard fetch/Cloudflare exceptions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →