Permanent URLs for agent-uploaded files and temporary rendered code images, built with ViteHub primitives.
Website · ViteHub · ViteHub docs · ViteHub on GitHub
- Blob stores uploaded files permanently and keeps rendered code images under a separate temporary prefix.
- PNG, JPEG, and WebP uploads continue through image optimization; other files are complete as soon as they are stored.
- Queue dispatches image optimization to a Cloudflare Sandbox while the original upload URL is already usable.
- Sharp applies EXIF orientation, strips metadata, and resizes images to fit within 2048 × 2048 without upscaling.
- Schedule runs hourly and deletes expired code images from their prefix without touching uploaded files.
- Drop replaces an uploaded Blob only when the optimized image is smaller. Nitro renders the current stored-file count into the landing page.
The Sandbox is a real npm project in server/sandboxes/image-optimizer. ViteHub materializes that project through Workspace and executes it through the selected Box provider.
Install the public agent skill:
npx skills add https://drop.vitehub.devThe bundled command uploads and immediately prints the file URL:
node "<skill-directory>/scripts/upload-image.mjs" "/absolute/path/to/file.pdf"Or use the API directly:
curl --fail-with-body https://drop.vitehub.dev/api/files \
-F "file=@/absolute/path/to/file.pdf"Files up to 4 MiB are accepted. PNG, JPEG, and WebP files are optimized when that makes them smaller; PDFs, spreadsheets, documents, archives, and other files are stored unchanged. The public deployment limits uploads to five attempts per source address per minute.
The code API opens Ray.so through a ViteHub Browser Definition, applies the requested language, theme, and export scale, then uses Ray's native PNG or SVG export. Treat the URL as available for five minutes; an hourly ViteHub Schedule removes expired code images without touching permanent uploads.
curl --fail-with-body https://drop.vitehub.dev/api/code \
-H "content-type: application/json" \
--data '{"code":"const answer: number = 42","language":"typescript","theme":"midnight","format":"png","scale":4}'The response contains the temporary Drop URL and its expiry:
{
"url": "https://drop.vitehub.dev/i/code-images/1785240300000/4aa...png",
"expiresAt": "2026-07-28T12:05:00.000Z"
}code is required and accepts up to 20,000 characters. format accepts png or svg, while scale accepts 2, 4, or 6 and affects PNG exports. Both default to Ray's primary export settings: PNG at 4×. language and theme are optional, case-sensitive IDs discovered through the Drop skill. When the image needs a permanent URL, download it before expiresAt and upload it through /api/files.
Drop targets Cloudflare automatically with the deployment name vitehub-drop:
pnpm install
pnpm buildCloudflare Sandbox requires a Workers Paid plan. Create the R2 bucket and Queue named by .output/server/wrangler.json, then deploy that generated configuration:
pnpm exec wrangler r2 bucket create vitehub-drop
pnpm exec wrangler queues create QUEUE_NAME_FROM_WRANGLER_JSON
pnpm exec wrangler deploy --config .output/server/wrangler.jsonViteHub composes the R2, Queue, Rate Limit, Sandbox, Container, Durable Object, and migration bindings, then emits the hourly Cron Trigger from the Schedule Definition.
Run the deployed smoke test:
pnpm test:e2e:deployedThe test uploads public/og-vitehub-drop.png to the production URL and confirms the returned image is publicly accessible.
The hand mark is Twemoji via Iconify, licensed under CC BY 4.0.