Cobweb GitHub issue

vibecode
{"vibecode": {
    "doc": "cobweb",
    "status": "brainstorm — code name confirmed 2026-05-22 (Midsummer fairy, parallel to Puck and Peaseblossom)",
    "role": "puck.uno image-modification service — submit an image plus a set of transformations, receive the transformed image bytes",
    "surface": "Puck protocol object AND standalone HTTP API (so any client, including Dogberry, can use it without a Puck dependency)",
    "ties": "Cobweb is to images what Markie is to HTML. Dogberry consumes Cobweb the same way Donnie consumes Markie — Cobweb does the transform, Dogberry handles the hosting context.",
    "example_universe": "shakespeare"
}}

Cobweb is an image-modification service offered at cobweb.uno (or wherever; name TBD). Submit an image — bytes uploaded with the request, or a URL Cobweb fetches — plus a description of the transformations you want, and Cobweb returns the modified image bytes. Rotate, resize, crop, convert format, adjust quality, strip metadata, apply filters, watermark.

Cobweb pairs naturally with Dogberry's image-modifications feature: a request like myshop.com/daisy.png?rotate=90 is Dogberry recognizing the query string, fetching the source, and calling Cobweb to do the rotate. But Cobweb is also standalone — any client can POST an image and get a transformed one back, no Puck or Dogberry needed.

Operations GitHub issue

vibecode
{"vibecode": {
    "section": "operations",
    "role": "the transformation vocabulary Cobweb understands; query-parameter form shown for each"
}}

Rotate GitHub issue

?rotate=N — rotate by N degrees clockwise. Common values: 90, 180, 270. Arbitrary values produce transparent-cornered output for formats that support alpha.

Resize GitHub issue

?width=N or ?height=N or ?width=N&height=N. Specifying only one preserves aspect ratio. Specifying both squashes unless a fit mode is also given (fit=contain, fit=cover, fit=stretch).

Crop GitHub issue

?crop=W,H,X,Y — crop to a W×H box anchored at (X, Y). Coordinates are pixels from top-left; convenience aliases (crop=center, crop=top, etc.) cover common cases.

Format conversion GitHub issue

?format=webp (or png, jpeg, avif, gif). The output is encoded in the requested format; the response Content-Type reflects the conversion.

Quality GitHub issue

?quality=N — encoder quality, 1–100, for lossy formats (JPEG, WebP, AVIF). Ignored for PNG and GIF.

Color filters GitHub issue

?grayscale, ?sepia, ?invert. The starter set of pixel-mapping filters. More can be added without breaking existing URLs.

Strip metadata GitHub issue

?strip — remove EXIF, ICC profiles, and other non-pixel metadata. Useful before serving public images (privacy, file size).

Composite GitHub issue

?overlay=url&overlay-position=top-right — composite another image (watermark, badge) onto the source. Position aliases plus pixel offsets.

Chained transforms GitHub issue

Multiple operations apply in URL order: ?width=400&rotate=90&format=webp resizes first, then rotates, then encodes as WebP. The order matters (rotating before resizing produces different output than the reverse).

API surfaces GitHub issue

vibecode
{"vibecode": {
    "section": "api_surfaces",
    "role": "the ways to call Cobweb"
}}

REST POST with image bytes GitHub issue

POST https://cobweb.uno/transform?<params> with the image in the request body. Returns the transformed bytes with the appropriate Content-Type. The canonical no-dependency API.

REST GET from URL GitHub issue

GET https://cobweb.uno/transform?source=https://...&<params> — Cobweb fetches the source URL, transforms, returns. Used by Dogberry; useful for any client that already has the image at an HTTP-reachable location.

Puck protocol object GitHub issue

%['cobweb.uno'].transform(source: ..., width: 400, rotate: 90) from Caspian. First-class Puck integration; lets Caspian code transform images without HTTP plumbing.

Caching GitHub issue

vibecode
{"vibecode": {
    "section": "caching",
    "role": "Cobweb's own response cache, separate from any caller-side cache"
}}

Content-addressed GitHub issue

The cache key is the hash of (source image bytes + transformation params). Identical input + identical params yields a cache hit even if the request URL differs. Lets Cobweb deduplicate aggressively across callers.

TTL bounded by source GitHub issue

For GET-from-URL requests, the cache entry's TTL is bounded by the source's Cache-Control. For POST requests, the TTL is Cobweb-side configurable.

Security GitHub issue

vibecode
{"vibecode": {
    "section": "security",
    "role": "the rules that keep Cobweb from being a free image-fetching proxy or a resource-exhaustion target"
}}

URL allowlist (GET form) GitHub issue

The GET-from-URL endpoint refuses fetches to private IP ranges (RFC 1918, loopback, link-local) and customer-configurable allowed-domains lists. Prevents Cobweb from being used to probe internal networks.

Input size limits GitHub issue

Maximum source size (in bytes and in pixel dimensions) prevents resource-exhaustion attacks. Configurable per account.

Output size limits GitHub issue

Maximum output dimensions prevent ?width=999999 from allocating gigabytes. Hard cap regardless of account.

Format allowlist GitHub issue

Cobweb only decodes well-known image formats. Random binary payloads are rejected before any decoder runs.

Animated images GitHub issue

vibecode
{"vibecode": {
    "section": "animated",
    "role": "GIF / WebP / APNG handling; the design decision is whether to preserve animation or rasterize the first frame"
}}

Animated formats (GIF, animated WebP, APNG) need a design decision: preserve animation through transforms (more expensive), or rasterize the first frame to a still (cheaper, common-case). Likely both, with a ?animated=preserve flag. Defaults TBD.

Open questions GitHub issue

Domain GitHub issue

cobweb.uno? A subpath under puck.uno? Both?

Image processing engine GitHub issue

ImageMagick (the obvious default, but heavy), libvips (faster, less coverage), Sharp (Node-only), in-house. Influences which formats and operations are supported with what performance.

SVG handling GitHub issue

SVG is vector, not raster. Some transforms (rotate, color filters) apply naturally; others (quality, format conversion to raster) require rasterization first. Worth thinking through what's well-defined for SVG inputs.

Self-hostable GitHub issue

A customer with their own infrastructure might want to run Cobweb locally — for compliance, latency, or cost reasons. Open-source the implementation, or hosted-only?

Relationship to Markie GitHub issue

Both Cobweb and Markie are "transformer-as-a-service" Puck objects. Worth asking whether they should share an abstract framework (a generic "transform-this-with-these-params" base) or stay independent. Probably independent for now — premature abstraction.

© 2026 Puck.uno