diff --git a/.cursor/agents/api-spec-reviewer.md b/.cursor/agents/api-spec-reviewer.md new file mode 100644 index 00000000..11cec839 --- /dev/null +++ b/.cursor/agents/api-spec-reviewer.md @@ -0,0 +1,39 @@ +--- +name: api-spec-reviewer +description: Runs Redocly lint on OpenAPI JSON under static/, applies api-fix (lint and structure), then suggests api-eval for style and copy. Use proactively after editing static/**/*.json OpenAPI specs. +--- + +You are an OpenAPI lint specialist for Firefly Services API documentation repos. + +## Reference + +- Lint: `npm run lint:openapi -- ` · config: [redocly.yaml](../../redocly.yaml) +- Spec resolution: [.cursor/skills/_shared/resolve-api-spec.md](../skills/_shared/resolve-api-spec.md) +- Fix workflow: [api-fix/SKILL.md](../skills/api-fix/SKILL.md) — **lint and structure** +- Full audit: [api-eval/SKILL.md](../skills/api-eval/SKILL.md) + +## When invoked + +1. **Resolve spec** — Per resolve-api-spec (no `petstore.json` default). + +2. **Run lint** + ```bash + npm run lint:openapi -- + ``` + +3. **Classify output** + - **Lint and structure** — Fix using api-fix (Redocly findings + api-ref-structure.mdc). + - **Style/copy** — Do **not** auto-fix. List briefly and suggest `/api-eval` or `/api-review`. + +4. **Re-run lint** after fixes until clean or blocked. + +5. **Summary** + - Lint status (pass / remaining issues) + - If clean: suggest `/api-eval` when style or copy review may still be needed + - If copy issues were noticed but not fixed, point to `/api-review` + +## Constraints + +- Never invent a placeholder spec under `static/`. +- Never apply FFS style guide or description edits unless the user explicitly asks outside api-fix scope. +- Prefer minimal edits that satisfy Redocly only. diff --git a/.cursor/rules/api-ref-copy.mdc b/.cursor/rules/api-ref-copy.mdc new file mode 100644 index 00000000..f8e47955 --- /dev/null +++ b/.cursor/rules/api-ref-copy.mdc @@ -0,0 +1,42 @@ +--- +description: Summaries, descriptions, punctuation, and public-facing copy for OpenAPI specs +globs: static/**/*.json +alwaysApply: false +--- + +# API reference — copy and descriptions + +## Response descriptions (HTTP status lines) + +- **Title Case**, no trailing period. +- Standardize: `Success`, `Accepted`, `Bad Request`, `Unauthorized`, `Forbidden`, `Requested Resource Was Not Found`, `Too Many Requests`, `Internal Server Error`, `Input Validation Error`. + +## All other descriptions + +- Complete sentences with periods (operations, parameters, request bodies, schemas, headers). +- No trailing or leading spaces on parameter descriptions. +- Fix spelling and grammar (`eg` → `e.g.`, `etc.` → `etc.`). +- Proper acronyms: GUID, URL (not Guid, Url). +- Consistent terminology (e.g. Adobe Asset Link). + +## Summaries + +- Sentence case; no trailing period; no `API` suffix. +- Lowercase version labels: `v1`, `v2` (not `V1`). +- Clear, descriptive; `operationId` in camelCase. + +## Public-facing text + +User-visible strings must not contain internal-only information. + +**Scan:** `info`, `tags`, operation summaries/descriptions, parameters, schemas, examples (prose), enum descriptions. + +**Do not allow:** + +- Jira or ticket keys (e.g. `FFENT-8796`, `PROJ-123`) +- Internal codenames, internal service names, corp-only wiki URLs +- Authoring TODOs tied to tickets (e.g. `TODO: fix after FFENT-…`) + +**Allowed:** Public product names, customer error codes, placeholders (`{your_api_key}`), standard field names (`jobId`). + +Flag violations as **high** severity in eval/review output. `/api-fix` does **not** auto-fix copy — use `/api-review` or explicit ref-based edits. diff --git a/.cursor/rules/api-ref-examples.mdc b/.cursor/rules/api-ref-examples.mdc new file mode 100644 index 00000000..829bbc3d --- /dev/null +++ b/.cursor/rules/api-ref-examples.mdc @@ -0,0 +1,23 @@ +--- +description: Request and response example values for Redocly OpenAPI docs +globs: static/**/*.json +alwaysApply: false +--- + +# API reference — examples + +## Values + +- Prefer realistic dummy values users can copy and run. +- Avoid type placeholders like `"string"` when an example can be provided. +- Use `{your_presigned_get_url}` style placeholders (curly brackets) when a real URL is impractical. + +## Placement + +- Short placeholders in example **values**. +- Instructions ("Replace with your presigned GET URL…") in parameter or request-body **descriptions**, not inside example strings. + +## Patterns + +- Request: realistic URLs, `your-output.pdf`, plausible `jobId` UUIDs. +- Response: show async shape (`jobId`, `statusUrl`, `status`) where applicable. diff --git a/.cursor/rules/api-ref-ffs-styleguide.mdc b/.cursor/rules/api-ref-ffs-styleguide.mdc new file mode 100644 index 00000000..ac583472 --- /dev/null +++ b/.cursor/rules/api-ref-ffs-styleguide.mdc @@ -0,0 +1,67 @@ +--- +description: Firefly Services API Style Guide checkpoints for api-eval (not api-fix) +globs: static/**/*.json +alwaysApply: false +--- + +# Firefly Services API Style Guide (eval only) + +**Wiki:** [Firefly Services API Style Guide](https://wiki.corp.adobe.com/display/GenAI/Firefly+Services+API+Style+Guide) + +Use with `/api-eval` only. `/api-fix` does **not** apply these unless Redocly flags them. + +**Offline checklist:** [.cursor/skills/api-eval/ffs-styleguide-checklist.md](../skills/api-eval/ffs-styleguide-checklist.md) + +## Scope + +Stateless Firefly Services RPC APIs. POST → async; GET (collections, status) → sync. + +## HTTP and URLs + +- POST operations: async 202 pattern. +- URL shape: `https://{subdomain}.adobe.io/v{version}/{operation-name}`. +- POST paths: verb-led, hyphenated (e.g. `/v2/generate-object-composite`). +- GET collections: plural nouns. + +## Async 202 response + +Required: `jobId`, `statusUrl`. Optional: `cancelUrl`. URLs: `…/v{version}/status/{jobId}`. + +## Status polling (GET) + +- `status`: `not_started`, `running`, `succeeded`, `failed`, `partially_succeeded`, `canceled`. +- `jobId` on all status responses. +- Failed: `error_code` or `errors[]` per Error Codes wiki. + +## Errors + +- 4xx/5xx and job failures: `error_code` required; `message` optional. +- Codes from [Error Codes wiki](https://wiki.corp.adobe.com/display/GenAI/API+Style+Guide%3A+Error+Codes). + +## JSON conventions + +- Property names: camelCase (except `error_code`). +- American English spellings. +- Suffixes: `*Date`, `*MediaType`, `*LocaleCode`, `*Folder`; plural names for arrays. +- Date-times: ISO 8601 with `Z`; locales: `en-US`. +- Media types: `enum` in OpenAPI spec. +- Omit null properties in responses (no `anyOf` with null for optional fields). + +## Resource objects + +Only: `url`, `uploadId`, or ACPC-related properties; optional `storageType` for Azure/Dropbox output URLs. + +## source / destination + +Recommended wrapper pattern for binary inputs/outputs with peer metadata. + +## POST → async (Jan 2026) + +Product POST endpoints should use the async calling pattern. + +## Severity + +- **error** — invalid OpenAPI or lint failure +- **high** — style guide contract violation +- **medium** — doc/copy vs modular rules +- **low** — suggestion diff --git a/.cursor/rules/api-ref-router.mdc b/.cursor/rules/api-ref-router.mdc new file mode 100644 index 00000000..efabd436 --- /dev/null +++ b/.cursor/rules/api-ref-router.mdc @@ -0,0 +1,35 @@ +--- +description: Route OpenAPI JSON work to api-eval, api-review, or api-fix skills +globs: static/**/*.json +alwaysApply: false +--- + +# API reference router + +When editing or reviewing OpenAPI JSON under `static/`, use the right skill. Load modular rules only when needed. + +## Task routing + +| User intent | Skill | Edits? | +|-------------|-------|--------| +| `/api-eval`, evaluate, audit | [api-eval](../skills/api-eval/SKILL.md) | No — findings only | +| `/api-review`, catalog descriptions | [api-review](../skills/api-review/SKILL.md) | No — tables for manual review | +| `/api-fix`, fix lint or structure | [api-fix](../skills/api-fix/SKILL.md) | Yes — **lint + api-ref-structure** | + +Resolve the spec path with [_shared/resolve-api-spec.md](../skills/_shared/resolve-api-spec.md). Do **not** assume `petstore.json`. + +## Non-negotiable description rule + +- **HTTP response `description`** (status lines): Title Case, **no** trailing period (e.g. `Internal Server Error`). +- **All other descriptions** (operations, parameters, schemas, headers): complete sentences **with** periods. + +## Modular rules (load on demand) + +- `api-ref-structure.mdc` — section order, license, JSON/$ref +- `api-ref-copy.mdc` — summaries, punctuation, public-facing text +- `api-ref-schema.mdc` — anyOf, type arrays, $ref/title +- `api-ref-examples.mdc` — Redocly examples +- `api-ref-tags-errors.mdc` — tags, errors, auth +- `api-ref-ffs-styleguide.mdc` — Firefly Services API Style Guide (api-eval only) + +Legacy monolith: `eval-API-ref.mdc` (deprecated stub). diff --git a/.cursor/rules/api-ref-schema.mdc b/.cursor/rules/api-ref-schema.mdc new file mode 100644 index 00000000..92056319 --- /dev/null +++ b/.cursor/rules/api-ref-schema.mdc @@ -0,0 +1,34 @@ +--- +description: OpenAPI schema patterns — anyOf, $ref, naming, OpenAPI 3.0 vs 3.1 +globs: static/**/*.json +alwaysApply: false +--- + +# API reference — schemas + +## Naming + +- Schemas: PascalCase, descriptive (e.g. `RemoveBackgroundRequest`). +- Properties: camelCase. +- Paths: descriptive kebab-case (e.g. `/v2/remove-background`). + +## anyOf + +- **Do not** use `anyOf` when the only alternative is `null` — omit from `required` instead. +- **Do not** use `anyOf` with a single option — use direct `$ref` or type. +- **Valid anyOf:** multiple real type alternatives (not null-only). + +## OpenAPI 3.1 only + +- Simplify primitive `anyOf` to type arrays: `"type": ["string", "array", "null"]`. +- OpenAPI **3.0** does not support multi-value type arrays — do not apply 3.1 patterns to 3.0 files. + +## $ref siblings + +- **Remove** `title` as sibling to `$ref` (ignored by tools, linter errors). +- **Keep** `description`, `deprecated`, `example` siblings where tools support them. +- Put titles on the referenced schema definition instead. + +## Organization + +- Group related schemas; avoid duplicates; use `$ref` (DRY). diff --git a/.cursor/rules/api-ref-skills.mdc b/.cursor/rules/api-ref-skills.mdc new file mode 100644 index 00000000..3a960b93 --- /dev/null +++ b/.cursor/rules/api-ref-skills.mdc @@ -0,0 +1,21 @@ +--- +description: Points to /api-eval, /api-review, and /api-fix skills for OpenAPI JSON in static/ +globs: static/**/*.json +alwaysApply: false +--- + +# API spec skills (`/api-eval`, `/api-review`, `/api-fix`) + +Agent skills for OpenAPI JSON under `static/`. Resolve the spec path with [_shared/resolve-api-spec.md](../skills/_shared/resolve-api-spec.md) — **no** `petstore.json` default. + +| Command | Skill | Edits? | +|---------|-------|--------| +| **`/api-eval`** | [api-eval/SKILL.md](../skills/api-eval/SKILL.md) | No — audit findings | +| **`/api-review`** | [api-review/SKILL.md](../skills/api-review/SKILL.md) | No — description catalog tables | +| **`/api-fix`** | [api-fix/SKILL.md](../skills/api-fix/SKILL.md) | Yes — Redocly lint + structure fixes | + +**Agent:** [api-spec-reviewer.md](../agents/api-spec-reviewer.md) — runs lint + api-fix after OpenAPI edits. + +**Lint:** `npm run lint:openapi -- static/your-spec.json` · `npm run lint:openapi:all` + +**FFS style guide wiki:** [Firefly Services API Style Guide](https://wiki.corp.adobe.com/display/GenAI/Firefly+Services+API+Style+Guide) diff --git a/.cursor/rules/api-ref-structure.mdc b/.cursor/rules/api-ref-structure.mdc new file mode 100644 index 00000000..8351ba12 --- /dev/null +++ b/.cursor/rules/api-ref-structure.mdc @@ -0,0 +1,43 @@ +--- +description: OpenAPI file structure, section order, license, and JSON validity +globs: static/**/*.json +alwaysApply: false +--- + +# API reference — structure + +## Section order + +Top-level keys in this order: + +1. `openapi` (version, always first) +2. `info` (include `license` when missing) +3. `servers` +4. `security` +5. `tags` +6. `paths` +7. `components` (always last) + +## License boilerplate + +When `info.license` is missing, add: + +```json +"license": { + "name": "Adobe Creative API License", + "url": "https://www.adobe.com/content/dam/cc/en/legal/terms/enterprise/pdfs/PSLT-AdobeCreativeAPI-WW-2024v2.pdf" +} +``` + +## Validity + +- Valid JSON syntax. +- All `$ref` paths resolve to existing schemas. +- No duplicate schema names in `components.schemas`. +- Verify `openapi` version (3.0.x vs 3.1.x) before applying version-specific schema rules. + +## File organization + +- Group related endpoints (operation + status) together. +- Organize schemas by function or alphabetically. +- Consistent indentation. diff --git a/.cursor/rules/api-ref-tags-errors.mdc b/.cursor/rules/api-ref-tags-errors.mdc new file mode 100644 index 00000000..4fa8867b --- /dev/null +++ b/.cursor/rules/api-ref-tags-errors.mdc @@ -0,0 +1,43 @@ +--- +description: OpenAPI tags, standard error responses, and authentication parameters +globs: static/**/*.json +alwaysApply: false +--- + +# API reference — tags, errors, auth + +## Tags + +- Descriptive sentence-case names with descriptions. +- Order logically; core operations first (e.g. "Common operations"). +- No empty tag arrays; avoid generic tags (`API`, product name only). + +## Standard error responses + +Include where appropriate: + +| Code | Description | +|------|-------------| +| 400 | Bad Request or Input Validation Error | +| 401 | Unauthorized | +| 403 | Forbidden | +| 404 | Requested Resource Was Not Found | +| 429 | Too Many Requests | +| 500 | Internal Server Error | + +Use Title Case, no periods on response descriptions. + +## Error schema + +- `error_code` (snake_case, gateway-aligned) and optional `message` on error payloads. + +## Authentication + +- Document `Authorization` (Bearer) as required. +- Document `x-api-key` as optional where Cluster Gateway applies. +- Consistent parameter naming across operations. + +## Versioning + +- Summaries include version: `Remove background v1`, `Get status - v2`. +- Beta: `v2 (beta)`; lowercase `vN`. diff --git a/.cursor/rules/cursor-rules.mdc b/.cursor/rules/cursor-rules.mdc index eb9660d2..fedfb599 100644 --- a/.cursor/rules/cursor-rules.mdc +++ b/.cursor/rules/cursor-rules.mdc @@ -33,7 +33,10 @@ Never place rule files: ## Project Agent skills (optional) -**Rules** (this folder) are always-on or glob-scoped instructions for the agent. **Skills** live under `PROJECT_ROOT/.cursor/skills//SKILL.md` and describe fuller workflows (for example stage-all-and-commit). If you add a skill, consider a short companion rule or a line in this file so contributors know it exists. For Git helpers: **`/gc`** commits after staging; **`/gcam`** stages, proposes a message, and waits for commit vs reject—see [.cursor/rules/gc-commit-skill.mdc](gc-commit-skill.mdc), [.cursor/skills/gc/SKILL.md](../skills/gc/SKILL.md), and [.cursor/skills/gcam/SKILL.md](../skills/gcam/SKILL.md). +**Rules** (this folder) are always-on or glob-scoped instructions for the agent. **Skills** live under `PROJECT_ROOT/.cursor/skills//SKILL.md` and describe fuller workflows (for example stage-all-and-commit). If you add a skill, consider a short companion rule or a line in this file so contributors know it exists. + +- **Git:** **`/gc`** · **`/gcam`** — [.cursor/rules/gc-commit-skill.mdc](gc-commit-skill.mdc), [.cursor/skills/gc/SKILL.md](../skills/gc/SKILL.md), [.cursor/skills/gcam/SKILL.md](../skills/gcam/SKILL.md) +- **OpenAPI JSON (`static/`):** **`/api-eval`** · **`/api-review`** · **`/api-fix`** — [.cursor/rules/api-ref-skills.mdc](api-ref-skills.mdc); agent [.cursor/agents/api-spec-reviewer.md](../agents/api-spec-reviewer.md) ## Naming conventions diff --git a/.cursor/rules/eval-API-ref.mdc b/.cursor/rules/eval-API-ref.mdc index 6f7d6d8d..f9e8f401 100644 --- a/.cursor/rules/eval-API-ref.mdc +++ b/.cursor/rules/eval-API-ref.mdc @@ -1,836 +1,31 @@ --- -description: How to edit API reference JSON files, particularly OpenAPI/Swagger specifications, for Firefly Services APIs -globs: static/*.json -alwaysApply: true +description: Deprecated — use api-ref-router and modular api-ref-* rules with api-eval skill +globs: static/**/*.json +alwaysApply: false --- -# API Reference Editing Guidelines - -This rule provides comprehensive guidelines for editing and maintaining API reference JSON files, particularly OpenAPI/Swagger specifications. - -## Tag Management - -### Tag Structure -- **Use descriptive tag names** that clearly indicate the functionality -- **Include tag descriptions** that explain what operations are grouped under each tag -- **Follow consistent naming conventions** (e.g., "Remove background", "Masking") -- **Avoid generic tags** like "API" or "Photoshop" - use specific functional tags instead - -### Tag Organization and Ordering -- **Order tags logically** - place most commonly used or core functionality first -- **Use "Common operations" or similar** for general/core endpoints that don't fit specialized categories -- **Group related functionality** under descriptive tag names -- **Ensure all endpoints have appropriate tags** - avoid empty tag arrays - -### Tag Examples -```json -"tags": [ - { - "name": "Common operations", - "description": "General Photoshop API operations and utilities" - }, - { - "name": "Masking", - "description": "Operations for creating and manipulating masks" - }, - { - "name": "Remove background", - "description": "AI-powered background removal and subject isolation operations" - } -] -``` - -## Endpoint Summary Guidelines - -### Format Requirements -- **Use sentence case**: First letter capitalized, rest lowercase -- **No trailing periods** -- **Remove "API" suffix** from summaries -- **Correct spelling and grammar** -- **Clear and descriptive** - should explain what the endpoint does -- **Consistent version formatting** - use lowercase for version numbers (e.g., "v1", "v2") - -### Summary Examples -```json -// Good examples -"summary": "Remove background v1" -"summary": "Create mask" -"summary": "Extract document manifest" -"summary": "Apply photoshop edits" -"summary": "Product crop" -"summary": "Get status - v2" - -// Bad examples -"summary": "Remove Background V1" // Title case -"summary": "Create Mask API." // Has "API" and period -"summary": "Prodct Crop" // Spelling error -"summary": "Get status - V2" // Inconsistent version capitalization -``` - -## Response Description Standards - -### Formatting Requirements -- **Use Title Case for all response descriptions** (e.g., "Success", "Internal Server Error") - **CRITICAL FOR READABILITY** -- **Maintain consistency across all status codes** (2xx, 4xx, 5xx) -- **Standardize common response descriptions** throughout the API -- **No trailing periods** - response descriptions should not end with periods -- **Professional appearance** - Title Case makes response descriptions more readable in Redocly documentation - -### Response Description Examples -```json -// Good examples - Title Case, no periods -"description": "Success" -"description": "Accepted" -"description": "Unauthorized" -"description": "Forbidden" -"description": "Bad Request" -"description": "Requested Resource Was Not Found" -"description": "Too Many Requests" -"description": "Internal Server Error" -"description": "Input Validation Error" -"description": "Trial Limit Exceeded Error" -"description": "Asset Link Invalid" -"description": "Unable To Upload Asset" - -// Bad examples - Inconsistent casing or periods -"description": "success" // Lowercase -"description": "Internal server error" // Mixed case -"description": "Too many requests" // Sentence case -"description": "InputValidationError" // No spaces -"description": "Success." // Has period -``` - -### Common Response Codes to Standardize -- **200/202**: "Success", "Accepted" -- **400**: "Bad Request", "Input Validation Error" -- **401**: "Unauthorized" -- **403**: "Forbidden" -- **404**: "Requested Resource Was Not Found" -- **429**: "Too Many Requests" -- **500**: "Internal Server Error" - -## Request and Response Examples (Redocly) - -### Example Value Guidance -- **Prefer realistic dummy values** in both request and response examples so users can copy, tweak, and run. -- **Use clear placeholder naming** when a dummy value isn't practical (e.g., `your-output.pdf`, `{your_asset_url}`). For placeholder tokens, **curly brackets are the recommended convention** (e.g., `{your_presigned_get_url}`)—they align with OpenAPI path parameter syntax and are widely recognized as "replace this." -- **Avoid type placeholders** like `"string"` when you can provide a realistic example. -- **Only use type placeholders** when no `example` or `examples` are provided and the doc is purely schema-generated. -- **Prefer placeholder tokens over instructional sentences in example values.** Use a short placeholder (e.g., `{source_image_url}` or a realistic dummy URL) in the example value, and put the instruction ("Replace with your presigned GET URL for the source image.") in the parameter or request-body description so the example stays copy-paste friendly. - -### Request Example Patterns -```json -// Good - realistic, copy-friendly -"examples": { - "default": { - "summary": "Example request", - "value": { - "input": "https://storage.example.com/template.ai", - "output": "your-output.pdf", - "outputFormat": "application/pdf" - } - } -} - -// Avoid - type placeholders -"example": { - "input": "string", - "output": "string", - "outputFormat": "string" -} -``` - -### Response Example Patterns -```json -// Good - realistic values that explain the shape -"examples": { - "success": { - "summary": "Job accepted", - "value": { - "jobId": "ff7b0f8e-47f3-4d8f-9a8b-7a9f9b2f4c42", - "statusUrl": "https://api.example.com/v1/jobs/ff7b0f8e-47f3-4d8f-9a8b-7a9f9b2f4c42", - "status": "accepted" - } - } -} -``` - -## Content Quality and Consistency - -### Description Content Standards -- **Complete sentences require periods** - all endpoint descriptions, parameter descriptions, and request body descriptions should be complete sentences with periods -- **Remove trailing spaces** from all descriptions -- **Fix spelling errors** (e.g., "returrn" → "return") -- **Use consistent terminology** across similar endpoints -- **Maintain professional tone** in all descriptions -- **Fix grammar issues** (e.g., "eg" → "e.g.", "etc" → "etc.") - -### Parameter Description Standards -- **Complete sentences with periods** - parameter descriptions should be complete sentences ending with periods -- **Remove leading spaces** from parameter descriptions -- **Use consistent formatting** for similar parameters -- **Provide clear, actionable descriptions** - -### Request Body Description Standards -- **Complete sentences with periods** - request body descriptions should be complete sentences ending with periods -- **Clear and descriptive** - explain what the request body contains -- **Consistent formatting** across similar endpoints - -### Content Review Checklist -- [ ] All response descriptions use Title Case (no periods) -- [ ] All non-response descriptions are complete sentences with periods -- [ ] No trailing spaces in descriptions -- [ ] No leading spaces in parameter descriptions -- [ ] Spelling errors corrected -- [ ] Grammar issues fixed (e.g., "eg" → "e.g.", "etc" → "etc.") -- [ ] Consistent terminology used -- [ ] All endpoints have appropriate tags -- [ ] Summary formatting follows sentence case guidelines -- [ ] Request and response examples use realistic dummy values - -## Schema Management - -### Schema Naming -- **Use descriptive, consistent naming** (e.g., `PhotoroomRemoveBackgroundRequest`) -- **Follow camelCase** for property names -- **Use clear, specific names** that indicate the purpose - -### Schema Organization -- **Group related schemas** together in the components section -- **Avoid duplicate schema definitions** -- **Use proper references** with `$ref` syntax -- **Include comprehensive descriptions** for complex schemas - -### AnyOf Convention with Null -The `anyOf` convention should **NOT** be used when the only alternative choice is `null`. This adds unnecessary complexity to the schema. - -#### Why This Matters -- **Simplicity** - Optional fields should be represented by omitting them from the `required` array, not by using `anyOf` with null -- **Readability** - Direct type declarations are clearer than wrapped anyOf structures -- **Standards compliance** - OpenAPI best practices favor simple optional fields over nullable unions -- **Documentation clarity** - Generates cleaner, more understandable API documentation - -#### How to Fix -Remove the `anyOf` wrapper and use the direct type definition. Fields that are optional should simply not be included in the schema's `required` array. - -#### Examples - -**❌ Bad - Using anyOf with null:** -```json -"message": { - "title": "Message", - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] -} -``` - -**✅ Good - Direct type definition:** -```json -"message": { - "title": "Message", - "type": "string" -} -``` - -**❌ Bad - Using anyOf with complex type and null:** -```json -"validation_errors": { - "title": "Validation Errors", - "anyOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/ValidationErrorMessage" - } - }, - { - "type": "null" - } - ] -} -``` - -**✅ Good - Direct array definition:** -```json -"validation_errors": { - "title": "Validation Errors", - "type": "array", - "items": { - "$ref": "#/components/schemas/ValidationErrorMessage" - } -} -``` - -**❌ Bad - Unnecessary anyOf with single option:** -```json -"result": { - "title": "Result", - "description": "The result of the job, if the job has completed.", - "anyOf": [ - { - "$ref": "#/components/schemas/GenerateObjectCompositeResponseV3" - } - ] -} -``` - -**✅ Good - Direct schema reference:** -```json -"result": { - "$ref": "#/components/schemas/GenerateObjectCompositeResponseV3" -} -``` - -#### Valid Uses of AnyOf -The `anyOf` keyword should only be used when there are **legitimate alternative types** that are not null: - -**✅ Valid - Multiple type alternatives:** -```json -"loc": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "string" - } - ] - } -} -``` - -**✅ Valid - Multiple schema alternatives:** -```json -"error_code": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/ErrorCodeEnum1" - }, - { - "$ref": "#/components/schemas/ErrorCodeEnum2" - } - ] -} -``` - -#### Detection Pattern -When reviewing API specifications, search for: -- `"anyOf"` followed by exactly two options -- One option being `{ "type": "null" }` -- These should be simplified to the non-null type only - -### Multi-Type Schema Simplification (OpenAPI 3.1) -When using **OpenAPI 3.1**, verbose `anyOf` structures with multiple primitive types should be simplified using type arrays for better readability and maintainability. - -#### Why This Matters -- **Improved readability** - Type arrays are more concise and easier to understand -- **Better maintainability** - Fewer lines of code to manage -- **Modern standards** - Aligns with OpenAPI 3.1 best practices -- **Cleaner documentation** - Generates more readable API docs in Redocly - -#### When to Simplify -Use type arrays instead of `anyOf` when defining a property that can be: -- **Multiple primitive types** (string, number, boolean, null, array, object) -- **Not** multiple schema references or complex combinations - -#### How to Simplify - -**❌ Bad - Verbose anyOf for multi-type properties:** -```json -"masks": { - "anyOf": [ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Masks" -} -``` - -**✅ Good - Simplified type array:** -```json -"masks": { - "type": ["string", "array", "null"], - "items": { - "type": "string" - }, - "title": "Masks" -} -``` - -**❌ Bad - Verbose anyOf without null:** -```json -"outputs": { - "anyOf": [ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } - ], - "title": "Outputs" -} -``` - -**✅ Good - Simplified type array:** -```json -"outputs": { - "type": ["string", "array"], - "items": { - "type": "string" - }, - "title": "Outputs" -} -``` -#### Valid Uses of AnyOf (Do Not Simplify) -Keep `anyOf` when dealing with: +# API reference guidelines (deprecated) -**✅ Valid - Multiple schema references:** -```json -"error_code": { - "anyOf": [ - { - "$ref": "#/components/schemas/ErrorCodeEnum1" - }, - { - "$ref": "#/components/schemas/ErrorCodeEnum2" - } - ] -} -``` +This monolith rule was split for efficiency. Use instead: -**✅ Valid - Mixed schema references and primitives:** -```json -"value": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/ComplexType" - } - ] -} -``` +## Skills -**✅ Valid - Complex type combinations with constraints:** -```json -"identifier": { - "anyOf": [ - { - "type": "string", - "format": "uuid" - }, - { - "type": "integer", - "minimum": 1 - } - ] -} -``` +| Command | Purpose | +|---------|---------| +| `/api-eval` | Audit: Redocly lint + OpenAPI version + FFS style guide + copy rules | +| `/api-review` | Catalog descriptions (ref tables with proposed content) | +| `/api-fix` | Fix **Redocly lint** and **structure** (`api-ref-structure.mdc`) | -#### Detection Pattern -When reviewing API specifications with OpenAPI 3.1, search for: -- `anyOf` arrays containing only primitive type definitions -- Multiple type objects without schema references or complex constraints -- These should be simplified to type arrays +See [api-ref-skills.mdc](api-ref-skills.mdc) and [.cursor/skills/](../skills/). -#### Important Notes -- This simplification **only applies to OpenAPI 3.1+** -- OpenAPI 3.0 does not support type arrays with multiple values -- Always verify your OpenAPI version before applying this pattern -- The `items` property is still needed for array types +## Rules -### Title Property as Sibling to $ref -The `title` property should **NOT** be used as a sibling to `$ref`. In OpenAPI 3.x, when using `$ref`, it replaces the entire object, and sibling properties like `title` are ignored by most tools and flagged as errors by linters. +- [api-ref-router.mdc](api-ref-router.mdc) — routing +- [api-ref-structure.mdc](api-ref-structure.mdc) +- [api-ref-copy.mdc](api-ref-copy.mdc) +- [api-ref-schema.mdc](api-ref-schema.mdc) +- [api-ref-examples.mdc](api-ref-examples.mdc) +- [api-ref-tags-errors.mdc](api-ref-tags-errors.mdc) +- [api-ref-ffs-styleguide.mdc](api-ref-ffs-styleguide.mdc) -#### Why This Matters -- **Ignored by tools** - Sibling properties to `$ref` don't appear in documentation -- **Linter errors** - Strict validators flag these as specification violations -- **Standards compliance** - Not part of the OpenAPI specification -- **Cleaner specs** - Removes unnecessary clutter - -#### What to Keep vs Remove -- **Remove:** `title` properties that are siblings to `$ref` -- **Keep:** `description` properties (these DO display in Redocly and provide valuable context) -- **Keep:** `deprecated`, `example`, and other metadata properties that tools may respect - -#### Examples - -**❌ Bad - Title as sibling to $ref:** -```json -"background": { - "$ref": "#/components/schemas/Background", - "title": "Background image", - "description": "The background scene and placement mask for object compositing." -} -``` - -**✅ Good - Only description kept:** -```json -"background": { - "$ref": "#/components/schemas/Background", - "description": "The background scene and placement mask for object compositing." -} -``` - -**❌ Bad - Title with $ref in allOf:** -```json -"size": { - "allOf": [ - { "$ref": "#/components/schemas/Size" } - ], - "title": "The size", - "description": "The desired width and height for the final image." -} -``` - -**✅ Good - Only description with $ref in allOf:** -```json -"size": { - "allOf": [ - { "$ref": "#/components/schemas/Size" } - ], - "description": "The desired width and height for the final image." -} -``` - -**✅ Good - Keep deprecated with description:** -```json -"mask": { - "allOf": [ - { "$ref": "#/components/schemas/PublicBinaryInputV3" } - ], - "description": "This is a deprecated property. Use `mask` instead.", - "deprecated": true -} -``` - -#### Where to Add Titles Instead -If you need descriptive titles, add them to the **referenced schema definition** itself: - -```json -"Background": { - "type": "object", - "title": "Background", - "description": "Defines the destination scene...", - "properties": { ... } -} -``` - -#### Detection Pattern -When reviewing API specifications, search for: -- Properties with both `"$ref"` and `"title"` at the same level -- These should have the `title` removed while keeping `description` if present -- Use linters to identify "Property title is not allowed" warnings - -## Endpoint Structure - -### Required Elements -- **Proper tags** assignment -- **Clear summary** following guidelines -- **Descriptive operationId** (camelCase) -- **Comprehensive description** explaining functionality -- **Complete request/response schemas** -- **Proper error handling** with appropriate HTTP status codes - -### Authentication -- **Include required authentication parameters** (Authorization, x-api-key) -- **Document authentication requirements** clearly -- **Use consistent parameter naming** - -## Error Handling - -### Standard Error Responses -Include these common error responses: -- **400** - Bad Request (Input Validation Error) -- **401** - Unauthorized -- **403** - Forbidden -- **404** - Requested Resource Was Not Found -- **429** - Too Many Requests -- **500** - Internal Server Error - -### Error Schema Structure -```json -"JobError": { - "type": "object", - "properties": { - "error_code": { - "type": "string", - "description": "The error code" - }, - "message": { - "type": "string", - "description": "The error message" - } - } -} -``` - -## Version Management - -### Endpoint Versioning -- **Use clear version indicators** in summaries (e.g., "v1", "v2 (beta)") -- **Maintain backward compatibility** when possible -- **Document version differences** in descriptions -- **Use consistent version formatting** (lowercase "v1", "v2") - -### Version Examples -```json -"summary": "Remove background v1" -"summary": "Remove background v2 (beta)" -"summary": "Get status - v2" -``` - -## File Organization - -### Structure Guidelines -- **Maintain logical endpoint grouping** by functionality -- **Keep related endpoints together** (e.g., main endpoint + status endpoint) -- **Organize schemas alphabetically** or by functional groups -- **Use consistent indentation** and formatting -- **Include `info.license`** when missing, using the Adobe Creative API License: https://www.adobe.com/content/dam/cc/en/legal/terms/enterprise/pdfs/PSLT-AdobeCreativeAPI-WW-2024v2.pdf - -### OpenAPI Section Ordering Convention -**Follow the standard OpenAPI 3.0 section order** to ensure consistency and readability: - -```json -{ - "openapi": "3.0.3", // 1. OpenAPI version (always first) - "info": { - /* API metadata */ - "license": { - "name": "Adobe Creative API License", - "url": "https://www.adobe.com/content/dam/cc/en/legal/terms/enterprise/pdfs/PSLT-AdobeCreativeAPI-WW-2024v2.pdf" - } - }, // 2. API information - "servers": [ /* Server configurations */ ], // 3. Server definitions - "security": [ /* Global security */ ], // 4. Global security schemes - "tags": [ /* Tag definitions */ ], // 5. API grouping tags - "paths": { /* Endpoint definitions */ }, // 6. API endpoints - "components": { // 7. Reusable components (always last) - "securitySchemes": { /* Authentication */ }, - "schemas": { /* Data models */ }, - "headers": { /* Custom headers */ }, - "responses": { /* Response definitions */ } - } -} -``` - -### Section Ordering Rules -- **openapi**: Must be first (version declaration) -- **info**: API metadata (title, description, version, contact, license) -- **servers**: Server configurations and base URLs -- **security**: Global authentication requirements -- **tags**: API operation grouping and organization -- **paths**: Endpoint definitions and operations -- **components**: Reusable schemas, responses, and security schemes (always last) - -### Section Ordering Validation -When reviewing API specifications, ensure sections follow this order: -1. ✅ **openapi** (version) - Always first -2. ✅ **info** (metadata) - API information -3. ✅ **servers** (configurations) - Server definitions -4. ✅ **security** (authentication) - Global security -5. ✅ **tags** (grouping) - API organization -6. ✅ **paths** (endpoints) - API operations -7. ✅ **components** (schemas) - Reusable definitions (always last) - -### Common Ordering Issues to Fix -- **servers section misplaced** - Should be after info, before security -- **security section misplaced** - Should be after servers, before tags -- **tags section misplaced** - Should be after security, before paths -- **components section misplaced** - Should always be last -- **Missing sections** - Ensure all required sections are present -- **Extra sections** - Remove any non-standard sections - -### Ordering Benefits -- **Improved readability** - Standard order helps developers navigate the spec -- **Better tooling support** - Many OpenAPI tools expect this order -- **Consistency** - Aligns with OpenAPI 3.0 specification standards -- **Maintainability** - Easier to locate and update specific sections - -## Quality Checks - -### Before Committing Changes -1. **Validate JSON syntax** - ensure valid JSON structure -2. **Check for duplicate schemas** - avoid naming conflicts -3. **Verify all $ref references** - ensure they point to existing schemas -4. **Review tag consistency** - ensure proper tagging across endpoints -5. **Test summary formatting** - follow sentence case, no periods, no "API" -6. **Validate OpenAPI specification** - use tools like Swagger Editor -7. **Review response descriptions** - ensure Title Case consistency (no periods) -8. **Check for content formatting issues** - ensure complete sentences with periods for non-response descriptions -9. **Verify grammar and spelling** - check for abbreviations and common errors -10. **Validate section ordering** - ensure sections follow OpenAPI 3.0 convention (openapi → info → servers → security → tags → paths → components) -11. **Check anyOf usage** - remove anyOf wrappers where the only alternative is null -12. **Simplify multi-type schemas** - for OpenAPI 3.1+, convert verbose anyOf structures with only primitive types to type arrays -13. **Remove title siblings to $ref** - remove title properties that are siblings to $ref (keep descriptions) - -### Common Issues to Avoid -- **Empty tag arrays** - assign appropriate tags or remove empty arrays -- **Inconsistent naming** - use consistent patterns across similar endpoints -- **Missing descriptions** - provide clear descriptions for all elements -- **Incomplete error handling** - include appropriate error responses -- **Spelling errors** - proofread all text content -- **Inconsistent response description casing** - use Title Case for all responses (no periods) -- **Incomplete sentences** - ensure all non-response descriptions are complete sentences with periods -- **Mixed version formatting** - use consistent lowercase version numbers -- **Grammar issues** - fix abbreviations like "eg" → "e.g." and "etc" → "etc." -- **Improper anyOf usage** - remove anyOf wrappers where the only alternative is null -- **Verbose multi-type schemas** - for OpenAPI 3.1+, simplify anyOf with only primitive types to type arrays -- **Title as sibling to $ref** - remove title properties that appear alongside $ref (keep descriptions) - -## Documentation Standards - -### Description Guidelines -- **Use clear, concise language** -- **Explain the purpose and functionality** -- **Include usage examples** where helpful -- **Document limitations or requirements** -- **Reference related endpoints** when applicable -- **Ensure complete sentences with periods** for all non-response descriptions -- **Use consistent terminology** - -### Example Description -```json -"description": "This endpoint allows you to remove the background from an image. The request is processed asynchronously and the status of the running job can be checked with the Get Status endpoint." -``` - -## Best Practices - -### General Guidelines -1. **Maintain consistency** across all endpoints -2. **Follow OpenAPI 3.0 specification** standards -3. **Use descriptive names** for all elements -4. **Include comprehensive documentation** -5. **Test the specification** with validation tools -6. **Review changes** before committing -7. **Keep schemas DRY** - avoid duplication -8. **Use proper data types** and constraints -9. **Standardize response descriptions** to Title Case (no periods) -10. **Organize tags logically** with core operations first -11. **Ensure complete sentences** for all non-response descriptions - -### Naming Conventions -- **Endpoints**: Use descriptive paths (e.g., `/v2/remove-background`) -- **Schemas**: Use PascalCase with descriptive names -- **Properties**: Use camelCase -- **Tags**: Use sentence case, descriptive names -- **Summaries**: Use sentence case, no periods, no "API" -- **Response descriptions**: Use Title Case, no periods -- **Non-response descriptions**: Use complete sentences with periods -- **Version numbers**: Use lowercase (v1, v2, v3) - -### Lessons Learned from Photoshop API Updates -- **Tag organization matters** - "Common operations" provides clear categorization for core endpoints -- **Response description consistency** - Title Case standardization improves readability (no periods) -- **Content formatting** - Complete sentences with periods improve professionalism for non-response descriptions -- **Version consistency** - Lowercase version numbers (v1, v2) are more readable -- **Spelling accuracy** - Even minor typos (like "returrn") should be corrected -- **Parameter description formatting** - Complete sentences with periods improve clarity -- **Grammar precision** - Abbreviations like "eg" should be "e.g." and "etc" should be "etc." -- **Trailing space removal** - Clean formatting improves readability -- **Complete sentence requirement** - All non-response descriptions should be complete sentences with periods -- **Distinction between response and non-response descriptions** - Response descriptions use Title Case (no periods), while all other descriptions use complete sentences with periods - -### Lessons Learned from InDesign API Review Session -- **OpenAPI section ordering** - Follow conventional order (openapi → info → servers → security → tags → paths → components) for better tooling support and readability -- **Response description Title Case** - All response descriptions should use Title Case for better readability and professional appearance -- **Header description formatting** - Response header descriptions need complete sentences with periods and proper grammar -- **Grammar consistency** - Fix "indicate" vs "indicates" and other verb agreement issues -- **Acronym standardization** - Use proper acronyms (e.g., "GUID" not "Guid", "URL" not "Url") -- **Sentence completion** - Complete incomplete sentences (e.g., "Header indicates how long..." → "Header indicates how long the results of a preflight request can be cached.") -- **Punctuation in examples** - Add proper punctuation to examples (e.g., "e.g." needs commas) -- **Consistent terminology** - Use "Adobe Asset Link" consistently, not "AEM Asset Link" -- **Property description clarity** - Improve vague descriptions (e.g., "ID" → "GUID ID for the job.") -- **Systematic review approach** - Review all 8 sections systematically: Info, Path, Parameters, Request Body, Responses, Schemas, Properties, and Headers -- **Comprehensive coverage** - Ensure all descriptions visible in Redocly documentation are reviewed and improved -- **User preference integration** - Incorporate user corrections and preferences while maintaining consistency -- **Batch processing efficiency** - Group similar corrections to reduce tool call overhead and improve efficiency - -## Section-by-Section Review Process - -### Systematic Review Strategy -- **Divide large files into logical sections** - group related schemas and endpoints together -- **Review one section at a time** - focus on quality rather than speed -- **Identify all issues before making changes** - create comprehensive lists of corrections needed -- **Apply corrections systematically** - address each issue type in batches -- **Verify changes after each section** - ensure no issues are missed - -### Section Organization Guidelines -- **Group by functionality** - related schemas and endpoints should be reviewed together -- **Logical progression** - start with core schemas, move to specialized ones -- **Consistent scope** - each section should be manageable (typically 50-100 lines) -- **Clear boundaries** - define section start/end points clearly - -### Quality Assurance Techniques -- **Cross-reference against identified issues** - ensure all listed problems are addressed -- **User feedback integration** - incorporate user preferences and corrections -- **Preserve user improvements** - maintain any manual corrections made by users -- **Verify against ruleset** - check that all changes align with established guidelines - -### Common Section Types -1. **Core Schema Sections** - fundamental data models and properties -2. **Endpoint Description Sections** - operation descriptions and parameters -3. **Component Schema Sections** - reusable data structures -4. **Options and Configuration Sections** - settings and preferences -5. **Response and Status Sections** - job status and output schemas -6. **Header and Security Sections** - authentication and metadata - -### User Preference Integration -- **Document user preferences** - record specific phrasings and formatting choices -- **Apply consistently** - use preferred descriptions across similar elements -- **Maintain user corrections** - preserve any manual improvements made during review -- **Consider context** - apply preferences appropriately based on element type - -### Error Prevention Strategies -- **Unique string identification** - use sufficient context to avoid duplicate string issues -- **Batch processing** - group similar corrections to reduce tool call overhead -- **Verification steps** - confirm changes were applied correctly -- **Rollback planning** - maintain ability to revert if needed - -### Review Completion Checklist -- [ ] All identified issues addressed -- [ ] User preferences applied consistently -- [ ] No new issues introduced -- [ ] Grammar and punctuation corrected -- [ ] Capitalization standardized -- [ ] Complete sentences with periods for non-response descriptions -- [ ] Title Case maintained for response descriptions (no periods) -- [ ] Technical terms properly capitalized -- [ ] Trailing spaces removed -- [ ] Section boundaries clearly defined -- [ ] AnyOf with only null alternatives removed and simplified -- [ ] Multi-type schemas simplified to type arrays (OpenAPI 3.1+ only) -- [ ] Title properties removed where they are siblings to $ref (descriptions kept) - ---- -description: API Reference editing guidelines with lessons learned from Photoshop API updates -globs: -alwaysApply: false ---- +Spec path resolution: [.cursor/skills/_shared/resolve-api-spec.md](../skills/_shared/resolve-api-spec.md). diff --git a/.cursor/skills/_shared/resolve-api-spec.md b/.cursor/skills/_shared/resolve-api-spec.md new file mode 100644 index 00000000..ca56908a --- /dev/null +++ b/.cursor/skills/_shared/resolve-api-spec.md @@ -0,0 +1,32 @@ +# Resolve OpenAPI spec path + +Use this procedure for `/api-eval`, `/api-review`, and `/api-fix`. **Do not** default to `petstore.json` or create placeholder specs. + +## Resolution order + +1. **Explicit path** — From the user message, `@` file reference, or skill argument (repo-relative or absolute). Use if the file exists and contains a top-level `"openapi"` field. + +2. **Active editor** — If the user has a JSON file open that is an OpenAPI spec, use that path. + +3. **Discover under `static/`** — Glob `static/**/*.json`. For each file, confirm OpenAPI (top-level `"openapi"` in the first ~30 lines). + - **One match** → use it; print `**Target spec:** \`path\`` at the start of skill output. + - **Multiple matches** → list paths and **ask the user to choose one** (or "all" only for `npm run lint:openapi:all`). Do not guess. + - **Zero matches** → report that no OpenAPI spec was found under `static/`; ask for a path. **Do not create a file.** + +4. **Redocly block hint (optional)** — If step 3 is ambiguous and `src/pages/api/index.md` exists, read `RedoclyAPIBlock` `src="..."` as a hint. Still confirm with the user when multiple specs exist. + +## Lint commands + +After resolving a single spec: + +```bash +npm run lint:openapi -- +``` + +For every OpenAPI file under `static/` (user requested only): + +```bash +npm run lint:openapi:all +``` + +`npm run lint:openapi` with no path argument: show usage — pass a spec path after `--`. diff --git a/.cursor/skills/api-eval/SKILL.md b/.cursor/skills/api-eval/SKILL.md new file mode 100644 index 00000000..7a5f3c1e --- /dev/null +++ b/.cursor/skills/api-eval/SKILL.md @@ -0,0 +1,54 @@ +--- +name: api-eval +description: Audits an OpenAPI JSON spec (Redocly lint, OpenAPI version, FFS style guide, copy rules). Read-only — no file edits. Use when the user invokes /api-eval or asks to evaluate or audit an API spec. +--- + +# `/api-eval` — Audit OpenAPI spec + +## When to run + +- User invokes `/api-eval`, "evaluate API spec", or "audit OpenAPI". +- **Do not edit files.** Findings only. + +## Steps + +1. **Resolve target spec** — Follow [_shared/resolve-api-spec.md](../_shared/resolve-api-spec.md). Print `**Target spec:** \`path\`` in the output header. + +2. **Layer 1 — Redocly lint** — Run: + ```bash + npm run lint:openapi -- + ``` + List every error/warning with path/line. Tag each as **`api-fix-eligible`** (`→ fix with /api-fix`). + +3. **Layer 2 — Structure** — Load [api-ref-structure.mdc](../../rules/api-ref-structure.mdc). Flag section order, missing license, broken `$ref`, duplicate schema names. Tag as **`api-fix-eligible`**. + +4. **Layer 3 — OpenAPI version** — Read `openapi` field. Audit 3.0 vs 3.1 rules per [api-ref-schema.mdc](../../rules/api-ref-schema.mdc) ($ref, type arrays, anyOf/null). Flag issues lint may miss. + +5. **Layer 4 — FFS style guide** — Load [api-ref-ffs-styleguide.mdc](../../rules/api-ref-ffs-styleguide.mdc) and [ffs-styleguide-checklist.md](ffs-styleguide-checklist.md). Flag **significant** contract inconsistencies only. + +6. **Layer 5 — Documentation** — Load `api-ref-copy`, `api-ref-examples`, `api-ref-tags-errors`. Check descriptions, examples, tags, **public-facing text** (no Jira/FFENT/codenames). + +7. **Output format** + - **Summary** — counts by layer and severity + - **Redocly lint** — numbered list (`api-fix-eligible`) + - **Structure** — numbered list (`api-fix-eligible`) + - **OpenAPI version** — findings + - **FFS style guide** — findings (wiki section if helpful) + - **Documentation / copy** — findings; suggest `/api-review` for full catalog + - Reminder: `/api-fix` = lint + `api-ref-structure`; copy/style = `/api-review` or `update refs N,M,…` + +## Severity + +- **error** — lint / invalid OpenAPI +- **high** — style guide or public-facing text violation +- **medium** — doc/copy inconsistency +- **low** — suggestion + +## Review completion checklist + +- [ ] Lint output included +- [ ] Structure (api-ref-structure) checked +- [ ] OpenAPI version checked +- [ ] FFS checkpoints reviewed +- [ ] Public-facing text (no internal IDs) +- [ ] No file edits made diff --git a/.cursor/skills/api-eval/ffs-styleguide-checklist.md b/.cursor/skills/api-eval/ffs-styleguide-checklist.md new file mode 100644 index 00000000..a9fd202f --- /dev/null +++ b/.cursor/skills/api-eval/ffs-styleguide-checklist.md @@ -0,0 +1,35 @@ +# FFS API Style Guide — eval checklist + +Source: [Firefly Services API Style Guide](https://wiki.corp.adobe.com/display/GenAI/Firefly+Services+API+Style+Guide) + +Related wiki pages: + +- [Error Codes](https://wiki.corp.adobe.com/display/GenAI/API+Style+Guide%3A+Error+Codes) +- [Pagination](https://wiki.corp.adobe.com/display/GenAI/API+Style+Guide%3A+Pagination) +- [ACP Integration](https://wiki.corp.adobe.com/display/GenAI/API+Style+Guide%3A+ACP+Integration) +- [Asynchronous Events](https://wiki.corp.adobe.com/display/GenAI/API+Style+Guide%3A+Asynchronous+Events) +- [Checklist](https://wiki.corp.adobe.com/display/GenAI/API+Style+Guide+checklist) + +## Eval layers + +1. Redocly lint + structure (`api-ref-structure.mdc`) — mark `api-fix-eligible` +2. OpenAPI version validity (3.0 vs 3.1) +3. FFS style guide (this checklist) +4. Doc modular rules (`api-ref-copy`, examples, tags) + +## Checklist + +- [ ] Stateless RPC scope; POST async, GET sync +- [ ] POST paths verb-led, hyphenated; GET collections plural nouns +- [ ] `Authorization` required; `x-api-key` optional where documented +- [ ] 202 body: `jobId`, `statusUrl`; optional `cancelUrl` +- [ ] Status enum: `not_started`, `running`, `succeeded`, `failed`, `partially_succeeded`, `canceled` +- [ ] Errors use `error_code`; optional `message` +- [ ] JSON camelCase (except `error_code`); American English +- [ ] `*Date`, `*MediaType`, `*LocaleCode`, `*Folder` naming +- [ ] ISO 8601 date-times; `en-US` locales +- [ ] Media types as OpenAPI `enum` +- [ ] Optional fields omitted, not `null` unions +- [ ] Resource objects: `url`, `uploadId`, or ACPC props only +- [ ] `source` / `destination` pattern where applicable +- [ ] POST endpoints use async pattern diff --git a/.cursor/skills/api-fix/SKILL.md b/.cursor/skills/api-fix/SKILL.md new file mode 100644 index 00000000..d65ed88a --- /dev/null +++ b/.cursor/skills/api-fix/SKILL.md @@ -0,0 +1,45 @@ +--- +name: api-fix +description: Fixes Redocly lint errors and api-ref-structure.mdc inconsistencies on an OpenAPI JSON spec. Use when the user invokes /api-fix or asks to fix API lint or structure issues. Does not apply FFS style guide or copy fixes. +--- + +# `/api-fix` — Fix lint and structure + +## Scope + +Apply **mechanical** fixes from two sources: + +1. **Redocly lint** — issues reported by `npm run lint:openapi -- ` +2. **Structure** — inconsistencies with [api-ref-structure.mdc](../../rules/api-ref-structure.mdc) + +Do **not** apply FFS style guide changes, copy edits, description punctuation, internal IDs, examples polish, or `api-ref-schema` / `api-ref-copy` findings unless Redocly flags them. + +## Steps + +1. **Resolve target spec** — [_shared/resolve-api-spec.md](../_shared/resolve-api-spec.md). + +2. **Run lint** — Record all errors/warnings. + +3. **Structure pass** — Load [api-ref-structure.mdc](../../rules/api-ref-structure.mdc). Fix: + - Top-level **section order**: `openapi` → `info` → `servers` → `security` → `tags` → `paths` → `components` + - Missing **`info.license`** (Adobe Creative API License boilerplate) + - **Validity** issues lint may not cover: broken `$ref`, duplicate schema names (when clearly wrong) + - Reorder keys only; do not rewrite endpoint or schema semantics + +4. **Lint pass** — Fix each Redocly finding with minimal change. Cite rule/message. + +5. **Re-run lint** until zero errors (warnings per [reference.md](reference.md)). + +6. **Re-check structure** — Confirm section order and license after lint edits. + +7. **Report** — Separate what was fixed under **Lint** vs **Structure**. If clean but style/copy issues remain, say: *Run `/api-eval` for style guide and documentation findings.* + +## Out of scope + +- FFS async shapes, `error_code` alignment, tags, summaries, public-facing text +- `anyOf`/type-array cleanup unless Redocly flags it +- Large refactors of file organization beyond section reorder and license + +## Reference + +See [reference.md](reference.md) for Redocly rules and structure checklist. diff --git a/.cursor/skills/api-fix/reference.md b/.cursor/skills/api-fix/reference.md new file mode 100644 index 00000000..f5ac2c26 --- /dev/null +++ b/.cursor/skills/api-fix/reference.md @@ -0,0 +1,34 @@ +# api-fix — Reference + +## Commands + +```bash +npm run lint:openapi -- static/your-product-spec.json +npm run lint:openapi:all +``` + +Config: [redocly.yaml](../../../redocly.yaml) at repo root. + +## Structure ([api-ref-structure.mdc](../../rules/api-ref-structure.mdc)) + +| Check | Action | +|-------|--------| +| Section order | Reorder top-level keys: openapi, info, servers, security, tags, paths, components | +| Missing license | Add `info.license` with Adobe Creative API License name and URL | +| Broken `$ref` | Correct path or add missing schema | +| Duplicate schema names | Rename or deduplicate in `components.schemas` | +| JSON syntax | Fix parse errors | + +## Common Redocly fixes + +| Issue | Typical fix | +|-------|-------------| +| Invalid `$ref` | Correct path or add missing schema | +| Sibling to `$ref` (e.g. `title`) | Remove sibling; move `title` to referenced schema | +| Invalid media type / schema | Align per Redocly message | + +## Not in api-fix scope + +- FFS style guide (api-eval) +- Description punctuation, public-facing text (api-review / manual edit) +- Schema anyOf simplification (api-ref-schema) unless lint flags it diff --git a/.cursor/skills/api-review/SKILL.md b/.cursor/skills/api-review/SKILL.md new file mode 100644 index 00000000..e934dabb --- /dev/null +++ b/.cursor/skills/api-review/SKILL.md @@ -0,0 +1,48 @@ +--- +name: api-review +description: Catalogs user-readable OpenAPI text in ref-numbered tables with possible issues and proposed content. Read-only unless user asks to update specific refs. Use when the user invokes /api-review or asks to review API descriptions. +--- + +# `/api-review` — Description catalog + +## When to run + +- User invokes `/api-review`, "review API descriptions", or "catalog schema descriptions". +- **Do not edit the JSON** unless the user later asks to `update refs N,M,…` (that is not `/api-fix`). + +## Steps + +1. **Resolve target spec** — [_shared/resolve-api-spec.md](../_shared/resolve-api-spec.md). Print `**Target spec:** \`path\``. + +2. **Collect text** — Walk the spec in document order. Assign **Ref** `1`, `2`, `3`, … to every user-readable `description` and `title` (where Redocly shows it). + +3. **Evaluate copy** — Load [api-ref-copy.mdc](../../rules/api-ref-copy.mdc). Fill **Possible issues** and **Proposed content** (when issues exist). + +4. **Emit sectioned tables** — One table per section below. **Location is always the last column.** + +### Table columns + +| Ref | Text (excerpt) | Possible issues | Proposed content | Location | +|-----|----------------|-------------------|------------------|----------| + +- **Text (excerpt):** ~80–120 chars; truncate with `…`. +- **Possible issues:** tags like `Missing period`, `Internal ID`, `Title Case on non-response`; `—` if none. +- **Proposed content:** customer-safe rewrite when issues exist; `—` if OK or no safe proposal. +- **Location:** JSON path + line number (e.g. `` `components/schemas/Foo.description` · L201 ``). + +### Section order + +1. Info and tags +2. Operations (summary, description) +3. Parameters and request bodies +4. Responses and headers +5. **Schemas** (primary focus) +6. Examples (prose in example strings only) + +5. **Footer** + - Total ref count + - *Lint → `/api-fix`. Copy → **Proposed content** or `update refs 3, 7, 12` (not `/api-fix`).* + +## Batch follow-up + +- `update refs 3, 7, 12` — Apply **Proposed content** at **Location** paths; preserve meaning. Not `/api-fix`. diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 44d6c6b7..622a14f0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -3,8 +3,6 @@ name: Lint on: pull_request: branches: [main] - paths: - - 'src/pages/**' jobs: lint: diff --git a/README.md b/README.md index c67e2ea0..4072176b 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,17 @@ This repo is the central hub repository for Firefly Services API documentation. Each Firefly Services API has its own repository, which is a spoke repository to this monorepo. Please see the [ADP Developer Site Documentation](https://developer-stage.adobe.com/dev-docs-reference/). + +## OpenAPI spec skills (Cursor) + +For OpenAPI JSON under `static/` in spoke repos (product-specific filenames, not a fixed `petstore.json`): + +| Command | Purpose | +|---------|---------| +| `/api-eval` | Audit: Redocly lint + OpenAPI version + [FFS API Style Guide](https://wiki.corp.adobe.com/display/GenAI/Firefly+Services+API+Style+Guide) + copy rules (no edits) | +| `/api-review` | Catalog descriptions in ref-numbered tables with proposed fixes (no edits) | +| `/api-fix` | Fix **Redocly lint** and **api-ref-structure** issues | + +Lint: `npm run lint:openapi -- static/your-spec.json` · `npm run lint:openapi:all` + +Details: [.cursor/rules/api-ref-skills.mdc](.cursor/rules/api-ref-skills.mdc) diff --git a/package.json b/package.json index cdcb5083..573cd870 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,9 @@ "link:externalLinkOnly": "npx --yes --prefer-online github:AdobeDocs/adp-devsite-utils runLint --external-links-only -v", "link:checkAllLinks": "npx --yes --prefer-online github:AdobeDocs/adp-devsite-utils runLint --internal-links-only --external-links-only -v", "redirectCheck:stage": "npx --yes --prefer-online github:AdobeDocs/adp-devsite-utils redirectChecker stage --verbose", - "redirectCheck:prod": "npx --yes --prefer-online github:AdobeDocs/adp-devsite-utils redirectChecker prod --verbose" + "redirectCheck:prod": "npx --yes --prefer-online github:AdobeDocs/adp-devsite-utils redirectChecker prod --verbose", + "lint:openapi": "npx --yes @redocly/cli@latest lint", + "lint:openapi:all": "sh -c 'if find static -name \"*.json\" -print -quit 2>/dev/null | grep -q .; then npx --yes @redocly/cli@latest lint static/; else echo \"No OpenAPI JSON files under static/\"; fi'" }, "engines": { "node": "^24.11.0" diff --git a/redocly.yaml b/redocly.yaml new file mode 100644 index 00000000..a3206369 --- /dev/null +++ b/redocly.yaml @@ -0,0 +1,10 @@ +# Redocly CLI config for OpenAPI specs under static/ +# Usage: npm run lint:openapi -- static/your-spec.json +# npm run lint:openapi:all + +extends: + - recommended + +apis: + static@latest: + root: static/