Skip to main content

code-storage

Agent skill for interacting with code.storage, a managed Git infrastructure layer. Provides repository creation, branching, commits, file access, diffs, search, notes, GitHub sync, ephemeral branches, and forking through a RESTful HTTP API authenticated with customer-signed JWTs. Every repo operation scoped per-JWT.

Source facts

Repository
pierrecomputer/sdk
Last source activity
September 17, 2026 at 19:23
Detected SKILL.md language
English
Stars
38
Forks
7

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
code-storage
description
Agent skill for interacting with code.storage, a managed Git infrastructure layer. Provides repository creation, branching, commits, file access, diffs, search, notes, GitHub sync, ephemeral branches, and forking through a RESTful HTTP API authenticated with customer-signed JWTs. Every repo operation scoped per-JWT.
MCP server: https://code.storage/docs/mcp Docs index: https://code.storage/docs/llms.txt Official SDKs (in this repository): - TypeScript / JavaScript: `@pierre/storage` (npm) - Python: `pierre-storage` (PyPI; import `pierre_storage`) - Go: `github.com/pierrecomputer/sdk/packages/code-storage-go` ## TypeScript custom HTTP transport `new GitStorage({ name, key, fetch })` (also `CodeStorage` and `createClient`) accepts an optional `fetch: typeof globalThis.fetch`. It applies to all SDK HTTP calls, including repository handles, downloads, and streaming commit uploads. The default is global fetch; the SDK adds no automatic retries. Callers own retry limits, backoff, cancellation, and safe body replay. Do not blindly retry writes or reuse consumed streaming request bodies. This option does not affect Git CLI traffic. See `packages/code-storage-typescript/README.md` for a read-only retry example. Python and Go do not use this TypeScript option. # ENVIRONMENT SETUP ## Required Environment Variables | Variable | Description | Example | |-------------------------|----------------------------------------------------------------|--------------------------------------------------| | `ORG_NAME` | Your organization identifier (subdomain slug) | `acme` | | `PIERRE_PRIVATE_KEY` | PEM-encoded EC (ES256) or RSA (RS256) private key | `-----BEGIN PRIVATE KEY-----\n...` | | `CODE_STORAGE_BASE_URL` | Derived base URL for HTTP API | `https://api.acme.code.storage/api/v1` | | `CODE_STORAGE_TOKEN` | JWT minted for current operation (per-repo or org-wide) | `eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...` | Export for curl sessions: ```bash export ORG_NAME="your-org" export CODE_STORAGE_BASE_URL="https://api.${ORG_NAME}.code.storage/api/v1" export CODE_STORAGE_TOKEN="YOUR_JWT_TOKEN" ``` ## JWT Token Structure Every request requires a JWT signed with your private key. Tokens are per-repository (except `org:read` which is org-wide). ```json { "iss": "your-org", // Organization identifier "sub": "@pierre/storage", // Subject (the SDKs set this to the package name) "repo": "team/project", // Repository the token grants access to "scopes": ["git:read", "git:write"], "refs": [ // Optional per-ref policy rules (first match wins) ["refs/heads/main", ["no-push"]], ["refs/heads/feature/*", ["no-force-push"]] ], "iat": 1723453189, "exp": 1723456789 } ``` JWT header: `{ "alg": "ES256", "typ": "JWT" }` (RS256 and EdDSA also supported) ### Policy Operations | Op string | SDK constant | Effect | |------------------|------------------------------------------------------------------------------|-------------------------------------------------------| | `no-force-push` | TS `OP_NO_FORCE_PUSH` / Py `OP_NO_FORCE_PUSH` / Go `storage.OpNoForcePush` | Rejects force pushes / non-fast-forward ref updates. | | `no-push` | TS `OP_NO_PUSH` / Py `OP_NO_PUSH` / Go `storage.OpNoPush` | Rejects any push to matching refs. | | `verify-sig` | TS `OP_VERIFY_SIG` / Py `OP_VERIFY_SIG` / Go `storage.OpVerifySig` | Rejects pushes introducing commits without a valid signature from a registered signing key. | #### Per-ref policies (preferred, use this for new code) The `refs` claim is an **ordered** array of `[pattern, [ops...]]` tuples. Rules are evaluated in declaration order. The first pattern that matches the ref wins. Patterns may be fully-qualified refs (`refs/heads/main`), prefix globs (`refs/heads/feature/*`, `refs/tags/*`), or `*` for every ref. Short branch names like `main` are normalized to `refs/heads/main` on verify. The policies are accepted by every URL-minting method and every ref-mutating REST method via the SDK option `refPolicies` (TS), `ref_policies` (Py), `RefPolicies` (Go). #### Repo-wide `ops` (legacy, do not use in new code) The optional top-level `ops` claim applies to every ref. On verify it is folded into the catch-all `*` rule. It is merged into an existing `*` entry in the ref policies when one is present, or appended as a new trailing `*` rule otherwise. Only available on the URL-minting methods (`getRemoteURL` / `getEphemeralRemoteURL` / `getImportRemoteURL`). Use `refPolicies: [{ pattern: '*', ops: [...] }]` instead. ```typescript await repo.getRemoteURL({ refPolicies: [ { pattern: 'refs/heads/main', ops: [OP_NO_PUSH] }, { pattern: '*', ops: [OP_NO_FORCE_PUSH] }, ], }); ``` ```python await repo.get_remote_url( ref_policies=[ {"pattern": "refs/heads/main", "ops": [OP_NO_PUSH]}, {"pattern": "*", "ops": [OP_NO_FORCE_PUSH]}, ], ) ``` ```go repo.RemoteURL(ctx, storage.RemoteURLOptions{ RefPolicies: storage.RefPolicyList{ {Pattern: "refs/heads/main", Ops: storage.Ops{storage.OpNoPush}}, {Pattern: "*", Ops: storage.Ops{storage.OpNoForcePush}}, }, }) ``` ### Permission Scopes | Scope | Grants | Required By | |--------------|---------------------------------|------------------------------------------------| | `git:read` | clone, fetch, pull, read API | GET file/branch/commit/diff/grep endpoints | | `git:write` | push, write API (includes read) | POST/DELETE commit/branch/note endpoints | | `repo:write` | create/delete repositories | POST /repos, DELETE /repos/delete | | `org:read` | list all repos in org | GET /repos (list) | ### Git Remote URL Format ``` https://t:{JWT}@{ORG_NAME}.code.storage/{REPO_ID}.git ``` Username is always `t`. Password is the JWT. # QUICK-REFERENCE ENDPOINT TABLE | Goal | Method | Endpoint | Scope Required | |-------------------------------|----------|-----------------------------------|-----------------| | **REPOSITORIES** | | | | | Create repository | POST | `/repos` | `repo:write` | | List all repositories | GET | `/repos` | `org:read` | | Get repository metadata | GET | `/repo` | (repo in JWT) | | Delete repository | DELETE | `/repos/delete` | `repo:write` | | **BRANCHES** | | | | | Create branch | POST | `/repos/branches/create` | `git:write` | | List branches | GET | `/repos/branches` | `git:read` | | Get branch diff | GET | `/repos/branches/diff` | `git:read` | | Preview merge | GET | `/repos/merge/preview` | `git:read` | | Merge branches | POST | `/repos/merge` | `git:write` | | Delete branch | DELETE | `/repos/branches` | `git:write` | | **COMMITS** | | | | | Create commit (file blobs) | POST | `/repos/commit-pack` | `git:write` | | Create commit from diff/patch | POST | `/repos/diff-commit` | `git:write` | | List commits | GET | `/repos/commits` | `git:read` | | Get commit | GET | `/repos/commit` | `git:read` | | Get commit diff | GET | `/repos/diff` | `git:read` | | Restore branch to commit | POST | `/repos/restore-commit` | `git:write` | | **FILES** | | | | | List files at ref | GET | `/repos/files` | `git:read` | | List files with metadata | GET | `/repos/files/metadata` | `git:read` | | Get file content (stream) | GET/HEAD | `/repos/file` | `git:read` | | Blame file at ref | GET | `/repos/blame` | `git:read` | | Search content (grep) | POST | `/repos/grep` | `git:read` | | Download archive (tar.gz) | POST | `/repos/archive` | `git:read` | | **TAGS** | | | | | Create tag | POST | `/repos/tags` | `git:write` | | List tags | GET | `/repos/tags` | `git:read` | | Delete tag | DELETE | `/repos/tags` | `git:read`+`git:write` | | **NOTES** | | | | | Create note on commit | POST | `/repos/notes` (action:"add") | `git:write` | | Append to note | POST | `/repos/notes` (action:"append") | `git:write` | | Get note for commit | GET | `/repos/notes?sha=SHA` | `git:read` | | Delete note | DELETE | `/repos/notes` | `git:write` | | List notes refs | GET | `/repos/notes/refs` | `git:read` | | **GIT SYNC** | | | | | Pull from upstream | POST | `/repos/pull-upstream` | `git:write` | | Detach upstream | DELETE | `/repos/base` | `git:write` | | **GENERIC GIT SYNC** | | | | | Create Git credential | POST | `/repos/git-credentials` | `repo:write` | | Update Git credential | PUT | `/repos/git-credentials` | `repo:write` | | Delete Git credential | DELETE | `/repos/git-credentials` | `repo:write` | All endpoints: `BASE_URL = https://api.{org}.code.storage/api/v1`
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub