Skip to content

Add agent-readable docs, AGENTS.md, and restructure README - #391

Open
const-cloudinary wants to merge 4 commits into
masterfrom
agent-docs
Open

const-cloudinary wants to merge 4 commits into
masterfrom
agent-docs

Conversation

@const-cloudinary

Copy link
Copy Markdown
Member

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.

Item Purpose
docs/ (16 pages) Task pages for agents using the SDK: credentials, dependency and first call, configuration, image upload, large/raw upload, signed browser upload, image and video delivery, search and asset management, moderation, structured metadata, Spring Boot, JSP taglib, troubleshooting, platform capabilities
examples/ (4 programs) Runnable versions of the upload, large-video upload, delivery, and search tasks
AGENTS.md, CLAUDE.md Contributor guide for agents; CLAUDE.md contains only @AGENTS.md
SECURITY.md Private reporting via GitHub advisories, plus server-side usage guidance
context7.json Context7 indexing; same account key as cloudinary_npm and pycloudinary
README.md Restructured to the same section list as the other Cloudinary SDKs
.gitignore Artifacts left behind by running the examples

README fixes: the install snippet named cloudinary-http45 with a 2.x version, which has never been published. It now names cloudinary-http5 with an X.Y.Z placeholder 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 jar

docs/ stays in the repository and is not added to any artifact.

  • Of 15 widely used Java libraries on Maven Central (Guava, OkHttp, Jackson, Gson, commons-lang3, SLF4J, Retrofit, AWS SDK v2, google-cloud-storage, Stripe, Twilio, SendGrid, java-jwt, Spring Core, jsoup), only jsoup ships any Markdown: a 3 KB README in META-INF/.
  • Embedding the pages would grow cloudinary-core by about 27% (175 KB → 223 KB) for files no runtime reads.
  • A resource inside a jar is not a file an agent can open without first locating the jar and unpacking it. Reading the repository at the matching release tag, or Cloudinary's llms.txt / .md documentation URLs, is shorter.

examples/ is not packaged either. Each doc page carries its complete flow inline.

Verification

Check Result
java snippets compile against the built 2.5.0 jars (fragments wrapped in a harness; Spring and servlet types stubbed) 103/103
Examples compile with --release 8 4/4
Internal links and cross-page anchors 0 errors
External URLs 37/38 return 200; the link to tree/master/docs resolves once this is merged
:cloudinary-http5:test, base (c9920c8) vs branch, each on a fresh product environment 206 tests, 0 failed, 39 skipped on both
:cloudinary-core:test on branch 275 tests, 0 failed

Behaviour 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

  • Context7: register cloudinary/cloudinary_java at context7.com. context7.json is inert until then.
  • Repository metadata: description, homepage, topics, and social preview.
  • CONTRIBUTING.md: the old README linked it, but it does not exist. The link was removed, not replaced.
  • docs: agent-optimize README + add AGENTS.md/CLAUDE.md and IDE pointer files #388 (outside PR) adds AGENTS.md/CLAUDE.md and IDE pointer files and overlaps with this one. Left open for a maintainer to decide.

🤖 Generated with Claude Code

- 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>
Comment thread docs/use-with-jsp-taglib.md Outdated
| `<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 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/use-with-jsp-taglib.md Outdated

```jsp
<cl:image src="docs_sample" format="jpg">
<cl:transformation width="300" height="200" crop="fill" gravity="auto"/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the above, this gives an untransformed image. Put the attributes on <cl:image> itself, or use the transformation="..." attribute.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The attributes now go on <cl:image> itself.

Comment thread docs/use-with-jsp-taglib.md Outdated
<cl:image src="docs_sample" width="300" height="200" crop="fill"/>
```

Chained transformations are successive `<cl:transformation>` elements:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/use-with-jsp-taglib.md Outdated
<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"/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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".

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/use-with-jsp-taglib.md Outdated
into a variable:

```jsp
<img src="<cl:url src='docs_sample' width='600' crop='fill' fetchFormat='auto' quality='auto'/>"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, fetchFormat='auto' -> fetch_format='auto'.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: fetch_format='auto', which renders f_auto.

Comment thread AGENTS.md Outdated
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()`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed from the list.

Comment thread AGENTS.md Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, 429 not mapping to RateLimited should be an issue, not a contract.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed from the list.

Comment thread AGENTS.md Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERSION drift is a release process bug, not a behaviour contract. Please remove.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Comment thread README.md Outdated
<artifactId>cloudinary-http45</artifactId>
<version>2.5.0</version>
<artifactId>cloudinary-http5</artifactId>
<version>X.Y.Z</version>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread README.md Outdated
## Usage
### Setup
```groovy
implementation 'com.cloudinary:cloudinary-http5:X.Y.Z'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

const-cloudinary and others added 3 commits October 29, 2026 20:55
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants