From 547e9bcd9475a0a907704eef26957f7b8c580214 Mon Sep 17 00:00:00 2001 From: dawid-ai Date: Mon, 20 Jul 2026 15:34:49 +0700 Subject: [PATCH] docs: agent-optimize README + add AGENTS.md/CLAUDE.md and IDE pointer files --- .cursor/rules/cloudinary.mdc | 8 ++ .github/copilot-instructions.md | 5 + AGENTS.md | 77 +++++++++++++++ CLAUDE.md | 34 +++++++ README.md | 164 +++++++++++++++++--------------- 5 files changed, 212 insertions(+), 76 deletions(-) create mode 100644 .cursor/rules/cloudinary.mdc create mode 100644 .github/copilot-instructions.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.cursor/rules/cloudinary.mdc b/.cursor/rules/cloudinary.mdc new file mode 100644 index 00000000..aa4444ed --- /dev/null +++ b/.cursor/rules/cloudinary.mdc @@ -0,0 +1,8 @@ +--- +description: Cloudinary CloudinaryDotNet — agent guide +alwaysApply: true +--- + +Read and follow `AGENTS.md` in the repository root. It is the single +authoritative guide for this package: build/test commands, conventions, +gotchas, and when to use this SDK versus a sibling Cloudinary package. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..cc0003b1 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,5 @@ +# Cloudinary CloudinaryDotNet — instructions for AI coding agents + +Read `AGENTS.md` in the repository root and follow it. It is the single +authoritative guide for this package: build/test commands, conventions, +gotchas, and when to use this SDK versus a sibling Cloudinary package. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..fc73a917 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,77 @@ +# AGENTS.md — CloudinaryDotNet + +## What this package is (one line) +Official server-side Cloudinary .NET SDK: upload assets, build transformation/delivery URLs, and call the Admin API from a C#/.NET backend that holds your `ApiSecret`. + +## When to use this / when NOT to use this +- **Use this when:** you are in a server-side .NET runtime (ASP.NET Core, Web API, worker service, console job) and need to upload assets, generate signed delivery URLs, or administer assets via the Admin API — work that must keep the `ApiSecret` private. +- **Do NOT use this when:** you only need to render delivery URLs in a **browser/frontend bundle** (that ships the secret to clients) — use `@cloudinary/url-gen` in JavaScript instead; or you want an autonomous/no-code agent path — use the Cloudinary MCP server. +- **Sibling packages:** `account-provisioning-dotnet` = the dedicated Provisioning API SDK for creating users, sub-accounts, and API keys (not this package). `@cloudinary/url-gen` = browser-side URL builder. Rule of thumb: code on a **server** → this package; code in a **browser** → not this package. + +## Setup +``` +PM> Install-Package CloudinaryDotNet +``` +Or via the CLI: +```bash +dotnet add package CloudinaryDotNet +``` +Required configuration / credentials. The parameterless constructor reads `CLOUDINARY_URL`: +```bash +export CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME +``` + +## Minimal runnable example +```csharp +using CloudinaryDotNet; +using CloudinaryDotNet.Actions; + +var cloudinary = new Cloudinary(); // reads CLOUDINARY_URL + +var uploadResult = cloudinary.Upload(new ImageUploadParams +{ + File = new FileDescription(@"c:\mypicture.jpg") +}); + +var url = cloudinary.Api.UrlImgUp + .Transform(new Transformation().Width(100).Height(150).Crop("fill")) + .BuildUrl("sample.jpg"); +``` + +## Build / test commands (run these after editing) +Solution file is `CloudinaryDotnet.sln`; target frameworks are `netstandard1.3;netstandard2.0;net452`. +```bash +dotnet restore CloudinaryDotnet.sln +dotnet build CloudinaryDotnet.sln -c Release + +# Unit tests — no network/credentials required: +dotnet test ./CloudinaryDotNet.Tests/CloudinaryDotNet.Tests.csproj -c Release + +# Integration tests — require LIVE Cloudinary credentials (see gotcha below): +dotnet test ./CloudinaryDotNet.IntegrationTests/CloudinaryDotNet.IntegrationTests.csproj -c Release + +# Pack a NuGet (build.ps1 wraps this): +dotnet pack -c Release -o lib +``` +(CI runs on AppVeyor (`appveyor.yml`), which runs the same two `dotnet test` projects — no separate `dotnet format`/lint step. The commands above drop the AppVeyor-only `--logger:Appveyor` / `--test-adapter-path:.` flags.) + +## Conventions & gotchas +- **Integration tests need a live account.** `CloudinaryDotNet.IntegrationTests` reads credentials from `CloudinaryDotNet.IntegrationTests/appsettings.json`. Copy `appsettings.json.sample` to `appsettings.json` and fill in `CloudName`/`ApiKey`/`ApiSecret` (CI provisions a throwaway sub-account via `before_build.ps1`). Without valid credentials these tests fail/hang — run `CloudinaryDotNet.Tests` (unit) for fast, offline feedback. +- **Run unit tests for normal edits;** only run integration tests when you change request building, signing, or API surface. +- **Server-side only.** The `ApiSecret` must never reach a browser bundle — that constraint is the reason this SDK exists. Do not add frontend/client-bundle code paths here. +- **Multi-target build.** Changes must compile against `netstandard1.3`, `netstandard2.0`, and `net452`; avoid APIs unavailable on the lowest target. +- **Public API surface:** consume types from `CloudinaryDotNet` and `CloudinaryDotNet.Actions` (as in the example); keep new public surface consistent with these namespaces. + +## Canonical docs (leave the repo for depth) +- .NET SDK guide: https://cloudinary.com/documentation/dotnet_integration +- Asset administration (Admin API): https://cloudinary.com/documentation/dotnet_asset_administration +- Transformation & REST API reference: https://cloudinary.com/documentation/cloudinary_references +- MCP server (agent/no-code path): https://github.com/cloudinary/mcp-servers + +## Agent / MCP note +If the task is exposed via the Cloudinary MCP servers, prefer the MCP tool for autonomous task execution and use this SDK for generated backend code. See cloudinary/mcp-servers. + +## Commit / PR conventions +- Ensure unit tests pass locally before opening a PR; CI must pass (it runs both unit and integration test projects). +- Use the repo `.github/pull_request_template.md` (it has a "what does this PR address" + tests-included + checklist form); see `CONTRIBUTING.md`. +- No formal commit-message convention (e.g. Conventional Commits) is documented. `CONTRIBUTING.md` only asks that a commit log "describe what changed and why," and that you squash commits into a single commit when appropriate. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..41343615 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,34 @@ +@AGENTS.md + +# CLAUDE.md — CloudinaryDotNet + +## What this repo is + +Official server-side Cloudinary .NET SDK. Handles upload, transformation/delivery URL building, and Admin API calls from a C#/.NET backend that holds the `ApiSecret`. + +## Key constraints + +- **Server-side only.** The `ApiSecret` must never reach a browser bundle. Do not add client-side code paths. +- **Multi-target build.** Code must compile against `netstandard1.3`, `netstandard2.0`, and `net452`. Avoid APIs unavailable on the lowest target. +- **Two separate test projects.** `CloudinaryDotNet.Tests` (unit — no credentials, fast) and `CloudinaryDotNet.IntegrationTests` (live account required). Run unit tests for normal edits; integration tests only when changing request building, signing, or API surface. +- **Integration tests need credentials.** Copy `CloudinaryDotNet.IntegrationTests/appsettings.json.sample` → `appsettings.json` and fill in `CloudName`/`ApiKey`/`ApiSecret` before running them. Without valid credentials these tests fail or hang. +- **Solution file is `CloudinaryDotnet.sln`** (lowercase 'n' in the filename). +- **Public namespaces:** `CloudinaryDotNet` and `CloudinaryDotNet.Actions`. Keep new public surface consistent with these. + +## Verified build / test commands + +```bash +dotnet restore CloudinaryDotnet.sln +dotnet build CloudinaryDotnet.sln -c Release + +# Unit tests — no network or credentials required: +dotnet test ./CloudinaryDotNet.Tests/CloudinaryDotNet.Tests.csproj -c Release + +# Integration tests — require live Cloudinary credentials: +dotnet test ./CloudinaryDotNet.IntegrationTests/CloudinaryDotNet.IntegrationTests.csproj -c Release + +# Pack a NuGet: +dotnet pack -c Release -o lib +``` + +CI runs on AppVeyor (`appveyor.yml`) — same two `dotnet test` projects, no separate lint step. diff --git a/README.md b/README.md index 19bdee60..f8c1678e 100755 --- a/README.md +++ b/README.md @@ -1,118 +1,130 @@ -[![Build status](https://ci.appveyor.com/api/projects/status/vdx8o03ethg5opt4?svg=true)](https://ci.appveyor.com/project/Cloudinary/cloudinarydotnet) -[![NuGet Badge](https://img.shields.io/nuget/v/CloudinaryDotNet)](https://www.nuget.org/packages/CloudinaryDotNet/) -![NuGet Downloads](https://img.shields.io/nuget/dt/CloudinaryDotNet) +# Cloudinary .NET SDK -Cloudinary .NET SDK -================== -## About -The Cloudinary .NET SDK allows you to quickly and easily integrate your application with Cloudinary. -Effortlessly optimize, transform, upload and manage your cloud's assets. +[![Build status](https://ci.appveyor.com/api/projects/status/vdx8o03ethg5opt4?svg=true)](https://ci.appveyor.com/project/Cloudinary/cloudinarydotnet) +[![NuGet version](https://img.shields.io/nuget/v/CloudinaryDotNet)](https://www.nuget.org/packages/CloudinaryDotNet/) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) +The `CloudinaryDotNet` package is the server-side Cloudinary SDK for .NET. Use it on a server or in a build step to upload assets, build transformation and delivery URLs, and call the Admin API. It holds your API secret, so it handles the operations that can't run in a browser: signed uploads, signed delivery URLs, and asset administration. The package multi-targets .NET Standard 1.3, .NET Standard 2.0, and .NET Framework 4.5.2 — any consumer on .NET Standard 2.0 or later (.NET Core 2.x/3.x, .NET 5-9, .NET Framework 4.6.1+) resolves the `netstandard2.0` build. The current release is 1.29.2. -#### Note -This Readme provides basic installation and usage information. -For the complete documentation, see the [.NET SDK Guide](https://cloudinary.com/documentation/dotnet_integration). +## Installation -## Table of Contents -- [Key Features](#key-features) -- [Version Support](#Version-Support) -- [Installation](#installation) -- [Usage](#usage) - - [Setup](#Setup) - - [Transform and Optimize Assets](#Transform-and-Optimize-Assets) +Using the .NET CLI: +```bash +dotnet add package CloudinaryDotNet +``` -## Key Features -- [Transform](https://cloudinary.com/documentation/dotnet_video_manipulation#video_transformation_examples) and - [optimize](https://cloudinary.com/documentation/dotnet_image_manipulation#image_optimizations) assets. -- Generate [image](https://cloudinary.com/documentation/dotnet_image_manipulation#deliver_and_transform_images) and - [video](https://cloudinary.com/documentation/dotnet_video_manipulation#dotnet_video_transformation_code_examples) tags. -- [Asset Management](https://cloudinary.com/documentation/dotnet_asset_administration). -- [Secure URLs](https://cloudinary.com/documentation/video_manipulation_and_delivery#generating_secure_https_urls_using_sdks). +Or the Package Manager console: +```powershell +Install-Package CloudinaryDotNet +``` +## Configuration -## Version Support +Create a `Cloudinary` instance and give it your credentials. The parameterless constructor reads them automatically from the `CLOUDINARY_URL` environment variable: -| SDK Version | .NET Framework 4.5.2 - 4.8 | .NET Standard 1.3 and up | .NET Core | .NET 5 - 9 | -|-------------|----------------------------|--------------------------|-----------|------------| -| 1.x | ✔ | ✔ | ✔ | ✔ | +```bash +CLOUDINARY_URL=cloudinary://:@ +``` -## Installation -CloudinaryDotNet is available as NuGet package [CloudinaryDotNet](https://nuget.org/packages/CloudinaryDotNet) +```csharp +using CloudinaryDotNet; -Install using Package Manager: +// Credentials come from CLOUDINARY_URL in the environment. +var cloudinary = new Cloudinary(); ``` -PM> Install-Package CloudinaryDotNet + +To set them in code instead, pass an `Account`: + +```csharp +using CloudinaryDotNet; + +var cloudinary = new Cloudinary(new Account("my_cloud_name", "my_key", "my_secret")); ``` -# Usage +Keep the API secret on the server. Don't put it in client-side code or commit it to version control. + +## Quick examples + +### Upload a file with the .NET SDK + +`Upload` takes an `ImageUploadParams` whose `File` is a `FileDescription` pointing at a local path or a remote URL. It returns an `ImageUploadResult` with `PublicId` and `SecureUrl`: -### Setup ```csharp using CloudinaryDotNet; using CloudinaryDotNet.Actions; +// Credentials come from CLOUDINARY_URL in the environment. var cloudinary = new Cloudinary(); -``` -### Transform and Optimize Assets -- [See full documentation](https://cloudinary.com/documentation/dotnet_image_manipulation). +var result = cloudinary.Upload(new ImageUploadParams +{ + File = new FileDescription(@"c:\my_image.jpg"), + PublicId = "cms/hero", // optional: where the asset lives in your media library +}); -```csharp -var url = cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(100).Height(150).Crop("fill")).BuildUrl("sample.jpg") +Console.WriteLine(result.PublicId); +Console.WriteLine(result.SecureUrl); // the https delivery URL ``` -### Upload -- [See full documentation](https://cloudinary.com/documentation/dotnet_image_and_video_upload). -- [Learn more about configuring your uploads with upload presets](https://cloudinary.com/documentation/upload_presets). +`UploadAsync(uploadParams)` returns the same `ImageUploadResult` as a `Task`. + +### Transform and optimize a delivery URL + +`Api.UrlImgUp` builds a URL synchronously — no network call. This resizes to a 100x150 fill crop and lets Cloudinary pick the format and quality for the requesting browser (`f_auto`, `q_auto`). Building a URL needs no API secret, so this instance is constructed with a cloud name only: + ```csharp -var uploadParams = new ImageUploadParams() -{ - File = new FileDescription(@"c:\mypicture.jpg") -}; +using CloudinaryDotNet; -var uploadResult = cloudinary.Upload(uploadParams); -``` +var cloudinary = new Cloudinary(new Account("demo")); -### Code Samples +var url = cloudinary.Api.UrlImgUp + .Secure(true) + .Transform(new Transformation() + .Width(100).Height(150).Crop("fill") + .FetchFormat("auto").Quality("auto")) + .BuildUrl("sample.jpg"); +// https://res.cloudinary.com/demo/image/upload/c_fill,f_auto,h_150,q_auto,w_100/sample.jpg +``` -You can find our simple and ready-to-use samples projects, along with documentations in the [samples folder](https://github.com/cloudinary/CloudinaryDotNet/tree/master/samples). +### Retrieve asset details -Please consult with the [README file](https://github.com/cloudinary/CloudinaryDotNet/blob/master/samples/README.md), for usage and explanations. +`GetResource` takes a public ID and returns the asset's metadata, including its format, dimensions, and `SecureUrl`: +```csharp +using CloudinaryDotNet; +using CloudinaryDotNet.Actions; -### Security options -- [See full documentation](https://cloudinary.com/documentation/solution_overview#security). +// Credentials come from CLOUDINARY_URL in the environment. +var cloudinary = new Cloudinary(); -## Contributions -- Ensure tests run locally -- Open a PR and ensure Travis tests pass +GetResourceResult asset = cloudinary.GetResource("sample"); +Console.WriteLine($"{asset.Format} {asset.Width}x{asset.Height} {asset.SecureUrl}"); +``` +`GetResourceAsync("sample")` returns the same `GetResourceResult` as a `Task`. -## Get Help -If you run into an issue or have a question, you can either: -- Issues related to the SDK: [Open a GitHub issue](https://github.com/cloudinary/CloudinaryDotNet/issues). -- Issues related to your account: [Open a support ticket](https://cloudinary.com/contact) +## For AI agents +`CloudinaryDotNet` is the .NET server-side SDK. Choose it for backend upload, asset administration, and signed URL or tag generation, where the API secret stays private. For other Cloudinary tasks, choose a different package: -## About Cloudinary -Cloudinary is a powerful media API for websites and mobile apps alike, Cloudinary enables developers to efficiently -manage, transform, optimize, and deliver images and videos through multiple CDNs. Ultimately, viewers enjoy responsive -and personalized visual-media experiences—irrespective of the viewing device. +| Task | Package | +|---|---| +| Provision users, product environments, and API keys in .NET | [`Cloudinary.Account.Provisioning`](https://github.com/cloudinary/account-provisioning-dotnet) | +| Build delivery URLs in the browser | [`@cloudinary/url-gen`](https://github.com/cloudinary/js-url-gen) | +| Render React, Angular, or Vue components | [`@cloudinary/react` / `@cloudinary/ng` / `@cloudinary/vue`](https://github.com/cloudinary/frontend-frameworks) | +| Run Cloudinary operations as agent tools | [Cloudinary MCP servers](https://github.com/cloudinary/mcp-servers) | +Every upload and admin method has an `async` variant (`UploadAsync`, `GetResourceAsync`, `Search().ExecuteAsync()`). Public types live in the `CloudinaryDotNet` and `CloudinaryDotNet.Actions` namespaces. -## Additional Resources -- [Cloudinary Transformation and REST API References](https://cloudinary.com/documentation/cloudinary_references): Comprehensive references, including syntax and examples for all SDKs. -- [MediaJams.dev](https://mediajams.dev/): Bite-size use-case tutorials written by and for Cloudinary Developers -- [DevJams](https://www.youtube.com/playlist?list=PL8dVGjLA2oMr09amgERARsZyrOz_sPvqw): Cloudinary developer podcasts on YouTube. -- [Cloudinary Academy](https://training.cloudinary.com/): Free self-paced courses, instructor-led virtual courses, and on-site courses. -- [Code Explorers and Feature Demos](https://cloudinary.com/documentation/code_explorers_demos_index): A one-stop shop for all code explorers, Postman collections, and feature demos found in the docs. -- [Cloudinary Roadmap](https://cloudinary.com/roadmap): Your chance to follow, vote, or suggest what Cloudinary should develop next. -- [Cloudinary Facebook Community](https://www.facebook.com/groups/CloudinaryCommunity): Learn from and offer help to other Cloudinary developers. -- [Cloudinary Account Registration](https://cloudinary.com/users/register/free): Free Cloudinary account registration. -- [Cloudinary Website](https://cloudinary.com): Learn about Cloudinary's products, partners, customers, pricing, and more. +## Links +- [.NET SDK guide](https://cloudinary.com/documentation/dotnet_integration) +- [Upload](https://cloudinary.com/documentation/dotnet_image_and_video_upload) +- [Asset administration (Admin API)](https://cloudinary.com/documentation/dotnet_asset_administration) +- [Transformation and API references](https://cloudinary.com/documentation/cloudinary_references) +- [Documentation llms.txt index](https://cloudinary.com/documentation/llms.txt) +- [Package on NuGet](https://www.nuget.org/packages/CloudinaryDotNet/) -## Licence Released under the MIT license.