← gitpulse
Merged
Size
M
Change Breakdown
New Feature70%
Tests10%
Dependencies10%
CI/CD10%
#52feat(cli): pluggable image storage with Vercel Blob impl (PR 1/3)

Image storage layer arrives with Vercel Blob

A pluggable storage interface lands in the CLI, giving the codebase a home for binary assets like AI-generated PR images. Vercel Blob is the first shipped provider.

GitPulse is getting images. Before the AI-generated PR illustrations can land, the infrastructure to store and retrieve binary assets needs to exist — and that infrastructure is the subject of this PR.

A new four-method interface covers the complete blob lifecycle: upload, resolve a public URL, list by prefix, and batch delete. The interface was audited against Vercel Blob, Cloudflare R2, AWS S3, and Supabase Storage before a line of implementation code was written, so swapping providers later requires no interface changes.

The first shipped implementation targets Vercel Blob. Public URLs follow a predictable pattern — the store ID lowercased and stripped of its prefix, then prefixed with Vercel's CDN domain — which means code can construct a URL without a round-trip to the SDK. The storeIdToHost helper handles the transformation; the urlFor method on the storage class uses it directly.

A createStorage factory accepts a StorageConfig discriminated union. The union reserves shapes for R2, S3, and Supabase today, even though only Vercel Blob is wired up. This keeps the Zod schema in project-config.ts stable when future providers arrive — the parser already knows those shapes exist.

Testing splits into two tracks. yarn test runs unit tests with all Vercel Blob calls mocked. yarn test:integration exercises the real API: upload, fetch (asserting 200), list, delete, then retry a 404 check for up to 10 seconds to handle Vercel Blob's CDN propagation lag. A CI workflow gates the integration suite on PRs and main pushes.

This is the first leg of a three-PR effort. PR 2 will add image generation and wire storage into the commit processing pipeline. PR 3 will add a workflow to clean up stale blobs when PRs close.