Repository navigation
Add agent-readable docs, AGENTS.md, and restructure README - #391
const-cloudinary wants to merge 4 commits into
Conversation
- docs/: 16 task pages for coding agents using the SDK (setup, upload, large/raw upload, signed browser upload, image/video delivery, search and asset management, moderation, structured metadata, Spring Boot, JSP taglib, troubleshooting, platform capabilities). Not packaged into any jar. - examples/: four runnable programs matching the doc pages. - AGENTS.md (with CLAUDE.md pointing to it): contributor guide for agents. - SECURITY.md: private reporting path and server-side usage guidance. - context7.json for Context7 indexing. - README.md: restructured; install snippet now names cloudinary-http5 with an X.Y.Z placeholder; fixed the GitHub issues link. - .gitignore: artifacts left by running the examples. No source changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
| | `<cl:image>` | Emit an `<img>` for a Cloudinary asset | | ||
| | `<cl:video>` | Emit a `<video>` element | | ||
| | `<cl:url>` | Emit just the URL string | | ||
| | `<cl:transformation>` | Nested inside the above, to describe a transformation | |
There was a problem hiding this comment.
This doesn't work. None of the taglib classes call getJspBody().invoke(), so the body of <cl:image> / <cl:video> / <cl:url> never runs. CloudinaryTransformationTag.doTag just prints transformation.generate() to the page. A nested <cl:transformation> has no effect on the parent tag.
There was a problem hiding this comment.
Fixed. The nested <cl:transformation> examples are gone, and the page now says the body of <cl:image>, <cl:video> and <cl:url> is not evaluated, so nesting has no effect. I rendered every JSP snippet on the page in Tomcat 9 to check.
|
|
||
| ```jsp | ||
| <cl:image src="docs_sample" format="jpg"> | ||
| <cl:transformation width="300" height="200" crop="fill" gravity="auto"/> |
There was a problem hiding this comment.
Because of the above, this gives an untransformed image. Put the attributes on <cl:image> itself, or use the transformation="..." attribute.
There was a problem hiding this comment.
Fixed. The attributes now go on <cl:image> itself.
| <cl:image src="docs_sample" width="300" height="200" crop="fill"/> | ||
| ``` | ||
|
|
||
| Chained transformations are successive `<cl:transformation>` elements: |
There was a problem hiding this comment.
Chaining doesn't work like this, same reason. It only works with the raw transformation attribute, whitespace becomes / (CloudinaryUrl.java:129-131). For example: transformation="c_fill,g_auto,h_400,w_400 e_sharpen f_auto,q_auto"
There was a problem hiding this comment.
Fixed. Chaining now uses transformation="c_fill,g_auto,h_400,w_400 e_sharpen f_auto,q_auto", which renders as c_fill,g_auto,h_400,w_400/e_sharpen/f_auto,q_auto.
| <cl:image src="docs_sample"> | ||
| <cl:transformation width="400" height="400" crop="fill" gravity="auto"/> | ||
| <cl:transformation effect="sharpen"/> | ||
| <cl:transformation fetchFormat="auto" quality="auto"/> |
There was a problem hiding this comment.
fetchFormat="auto" is dropped silently. Dynamic attributes go to Transformation.params() and generate() reads only snake_case keys (fetch_format / f). Should be fetch_format="auto".
There was a problem hiding this comment.
Fixed. That example is gone, and the page now says to use snake_case names (fetch_format); an unknown name such as fetchFormat is dropped silently.
| into a variable: | ||
|
|
||
| ```jsp | ||
| <img src="<cl:url src='docs_sample' width='600' crop='fill' fetchFormat='auto' quality='auto'/>" |
There was a problem hiding this comment.
Same here, fetchFormat='auto' -> fetch_format='auto'.
There was a problem hiding this comment.
Fixed: fetch_format='auto', which renders f_auto.
| by execution and described in `docs/`; changing one is a behaviour change for existing | ||
| callers: | ||
| 1. `Configuration.from()` parses with `java.net.URI`, so a cloud name containing an | ||
| underscore yields `null` cloud name, key, and secret (`getHost()` and `getUserInfo()` |
There was a problem hiding this comment.
Underscore cloud name giving null credentials looks like a bug. If we list it as public contract nobody will fix it. Better as a known issue with a ticket.
There was a problem hiding this comment.
Removed from the list.
| the Admin API, and `java.lang.UnknownError` (an `Error`, not an `Exception`) when no HTTP | ||
| adapter is present. | ||
| 3. `Api.CLOUDINARY_API_ERROR_CLASSES` maps HTTP 400/401/403/404/409/420/500 to typed | ||
| exceptions; other status codes become `GeneralError`. This includes 429, which is not |
There was a problem hiding this comment.
Same here, 429 not mapping to RateLimited should be an issue, not a contract.
There was a problem hiding this comment.
Removed from the list.
| 6. `Url.resourcType(String)` is retained alongside `resourceType(String)` for compatibility. | ||
| Both work. | ||
| 7. `Cloudinary.VERSION` and `version=` in `gradle.properties` are maintained separately and | ||
| can drift; during 2.3.x they read `2.3.1` and `2.3.2`. Both read `2.5.0` at the time of |
There was a problem hiding this comment.
VERSION drift is a release process bug, not a behaviour contract. Please remove.
| <artifactId>cloudinary-http45</artifactId> | ||
| <version>2.5.0</version> | ||
| <artifactId>cloudinary-http5</artifactId> | ||
| <version>X.Y.Z</version> |
There was a problem hiding this comment.
X.Y.Z breaks copy-paste for people. tools/update_version.sh:11 already updates the version in README.md on release, so we can keep the real version.
There was a problem hiding this comment.
Done. The README shows 2.6.0 again. The release script used grep -P, which macOS grep doesn't support, so on a Mac it changed nothing. It now uses sed; I tested it on macOS and Ubuntu.
| ## Usage | ||
| ### Setup | ||
| ```groovy | ||
| implementation 'com.cloudinary:cloudinary-http5:X.Y.Z' |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Read the version with sed instead of grep -P, use sed -i.bak so the in-place edit works with both GNU and BSD sed, and exit if the version cannot be read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Taglib: drop nested <cl:transformation> examples, use attributes and the transformation attribute, fetch_format, publicId and SingletonManager behaviour - Signed uploads: the upload must send exactly the signed parameters - Configuration: secure/analytics defaults per config path, first error for unparsed credentials, analytics opt-out, default timeout - Uploads: uploadLarge accepts an InputStream, buildUploadParams keys, per-file progress, Spring examples without Map.of or temp files - Five Api methods accept an asset ID; poster uses the middle frame - AGENTS.md: shorter, matches CI, drops the http4x and contract items - README shows the released version again Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Summary
Adds task documentation for AI coding agents that use the SDK, a contributor guide for agents working on this repository, and a restructured README. No source changes.
docs/(16 pages)examples/(4 programs)AGENTS.md,CLAUDE.mdCLAUDE.mdcontains only@AGENTS.mdSECURITY.mdcontext7.jsoncloudinary_npmandpycloudinaryREADME.md.gitignoreREADME fixes: the install snippet named
cloudinary-http45with a 2.x version, which has never been published. It now namescloudinary-http5with anX.Y.Zplaceholder and points to Maven Central for the current version. The GitHub issues link pointed at a non-existent org.Why
docs/is not packaged into a jardocs/stays in the repository and is not added to any artifact.META-INF/.cloudinary-coreby about 27% (175 KB → 223 KB) for files no runtime reads.llms.txt/.mddocumentation URLs, is shorter.examples/is not packaged either. Each doc page carries its complete flow inline.Verification
javasnippets compile against the built 2.5.0 jars (fragments wrapped in a harness; Spring and servlet types stubbed)--release 8tree/master/docsresolves once this is merged:cloudinary-http5:test, base (c9920c8) vs branch, each on a fresh product environment:cloudinary-core:teston branchBehaviour described in the pages was observed against live product environments while the pages were being written. The examples were run live, including no-credential and bad-credential runs, before the rebase onto 2.5.0. After the rebase they were compiled, not re-run.
Snippets are reference voice: they show correct usage and state documented behaviour.
Known limitation: the Spring Boot controller snippet uses
Map.of, which needs Java 9+. That matches Spring Boot 3 (Java 17).Needs a maintainer
cloudinary/cloudinary_javaat context7.com.context7.jsonis inert until then.CONTRIBUTING.md: the old README linked it, but it does not exist. The link was removed, not replaced.AGENTS.md/CLAUDE.mdand IDE pointer files and overlaps with this one. Left open for a maintainer to decide.🤖 Generated with Claude Code