Skip to main content

Installation & Setup

pnpm i @pierre/storage
# Using uv (recommended)
uv add pierre-storage

# Or using pip
pip install pierre-storage
go get github.com/pierrecomputer/sdk/packages/code-storage-go@latest
Initialize the client:
import { GitStorage } from "@pierre/storage";

const storage = new GitStorage({
  name: "your-org", // Your organization identifier
  key: env.privateKey,
});
from pierre_storage import GitStorage

storage = GitStorage({
    "name": "your-org",          # Your organization identifier
    "key": "your-private-key",   # Your API key in PEM format
})
// Initialize the client
client, err := storage.NewClient(storage.Options{
  Name: "your-org",
  Key:  "your-private-key",
})
In Go, SDK calls take a context.Context, and TTL values are time.Duration (for example time.Hour).
Need to generate JWTs yourself? See Authentication & security → Manual JWT generation.

Error Handling

The SDK surfaces API failures as ApiError and ref update failures as RefUpdateError.
import { ApiError, RefUpdateError, GitStorage } from "@pierre/storage";

const storage = new GitStorage({ name: "your-org", key: "your-private-key" });

try {
  const repo = await storage.createRepo({ id: "existing" });
  console.log(repo.id);
} catch (err) {
  if (err instanceof ApiError) {
    console.error("API error:", err.message);
    console.error("Status code:", err.statusCode);
  } else {
    throw err;
  }
}

const repo = await storage.findOne({ id: "repo-id" });
const builder = repo?.createCommit({
  targetBranch: "main",
  commitMessage: "Update docs",
  author: { name: "Docs Bot", email: "docs@example.com" },
});

try {
  const result = await builder
    ?.addFileFromString("docs/changelog.md", "# v2.0.1\n- add streaming SDK\n")
    .send();
  console.log(result?.commitSha);
} catch (err) {
  if (err instanceof RefUpdateError) {
    console.error("Ref update failed:", err.message);
    console.error("Status:", err.status);
    console.error("Reason:", err.reason);
    console.error("Ref update:", err.refUpdate);
  } else {
    throw err;
  }
}
from pierre_storage import ApiError, RefUpdateError

try:
    repo = await storage.create_repo(id="existing")
except ApiError as e:
    print(f"API error: {e.message}")
    print(f"Status code: {e.status_code}")

try:
    result = await builder.send()
except RefUpdateError as e:
    print(f"Ref update failed: {e.message}")
    print(f"Status: {e.status}")
    print(f"Reason: {e.reason}")
    print(f"Ref update: {e.ref_update}")
// Initialize the client
client, err := storage.NewClient(storage.Options{
  Name: "your-org",
  Key:  "your-private-key",
})

// Create a repository and handle API errors
_, err = client.CreateRepo(context.Background(), storage.CreateRepoOptions{ID: "existing"})
if err != nil {
  var apiErr *storage.APIError
  if errors.As(err, &apiErr) {
    fmt.Printf("API error: %s (status=%d)\n", apiErr.Message, apiErr.Status)
  } else {
    fmt.Printf("Unexpected error: %v\n", err)
  }
}

// Build a commit and handle ref update errors
repo, err := client.FindOne(context.Background(), storage.FindOneOptions{ID: "repo-id"})
builder, err := repo.CreateCommit(storage.CommitOptions{
  TargetBranch:  "main",
  CommitMessage: "Update docs",
  Author:        storage.CommitSignature{Name: "Docs Bot", Email: "docs@example.com"},
})

_, err = builder.AddFileFromString("docs/changelog.md", "# v2.0.1\n- add streaming SDK\n", nil).
  Send(context.Background())
if err != nil {
  var refErr *storage.RefUpdateError
  if errors.As(err, &refErr) {
    fmt.Printf("Ref update failed: %s (status=%s, reason=%s)\n", refErr.Message, refErr.Status, refErr.Reason)
  } else {
    fmt.Printf("Unexpected error: %v\n", err)
  }
}

Repository Properties

Once you have a repository instance from createRepo() or findOne(), these properties are available:
id
string
The repository identifier
defaultBranch
string
The repository’s default branch name (e.g., main)
const repo = await store.findOne({ id: "my-repo" });
console.log(repo.id); // 'my-repo'
console.log(repo.defaultBranch); // 'main'
repo = await storage.find_one(id="my-repo")
print(repo.id)              # 'my-repo'
print(repo.default_branch)  # 'main'
// Read repository properties
repo, err := client.FindOne(context.Background(), storage.FindOneOptions{ID: "my-repo"})
if repo != nil {
  // Access repo metadata
  fmt.Println(repo.ID)
  fmt.Println(repo.DefaultBranch)
}

Complete Example

import { GitStorage } from "@pierre/storage";

const storage = new GitStorage({
  name: "your-org",
  key: "your-private-key",
});

async function setupRepository() {
  // Create repository
  const repo = await storage.createRepo({
    id: "backend/api-service",
  });

  // Generate secure URL
  const url = await repo.getRemoteURL({
    permissions: ["git:read", "git:write"],
    ttl: 31536000, // 1 year
  });

  // Use with Git
  console.log(`git clone ${url}`);

  return repo;
}
from pierre_storage import GitStorage

storage = GitStorage({
    "name": "your-org",
    "key": "your-private-key",
})

async def setup_repository():
    repo = await storage.create_repo(id="backend/api-service")
    url = await repo.get_remote_url(
        permissions=["git:read", "git:write"],
        ttl=31536000,
    )
    print(f"git clone {url}")
    return repo
// Initialize Pierre client for code storage
client, err := storage.NewClient(storage.Options{
  Name: "your-org",
  Key:  "your-private-key",
})

// Create repository
repo, err := client.CreateRepo(context.Background(), storage.CreateRepoOptions{
  ID: "backend/api-service",
})

// Generate secure URL
url, err := repo.RemoteURL(context.Background(), storage.RemoteURLOptions{
  Permissions: []storage.Permission{storage.PermissionGitRead, storage.PermissionGitWrite},
  TTL:         365 * 24 * time.Hour,
})

// Use with Git
fmt.Printf("git clone %s\n", url)