@nitida/sdk 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md ADDED
@@ -0,0 +1,48 @@
1
+ # @nitida/sdk — for coding agents
2
+
3
+ **Read `skills/nitida-sdk/SKILL.md` in this package first.** It is the canonical guide and it
4
+ ships inside the tarball, so it is already on disk in `node_modules/@nitida/sdk/skills/`. It
5
+ carries the things that cost real incidents to learn — the base36 tenant prefix, the width ladder,
6
+ the `original`-preset trap, the R2 CORS boundary — not just the API shape.
7
+
8
+ **Then read `src/`.** This package publishes its TypeScript sources (`files: ["dist/**", "src/**"]`),
9
+ so the source *is* the reference: every public method carries TSDoc, and the ones worth copying
10
+ carry `@example` blocks. Read the source for the canonical, version-pinned answer rather than
11
+ recalling an API from training data — this SDK moves.
12
+
13
+ ## The five-minute version
14
+
15
+ ```ts
16
+ import { AquienpzClient } from "@nitida/sdk/server"; // uploads: server-only, holds the amk_rt_* key
17
+ import { getTransformUrl, setCdnBase, setTenantId } from "@nitida/asset-client"; // URLs: anywhere
18
+ ```
19
+
20
+ - **Uploading** → `aq.upload(file, { fileName, contentType, presets })`. One call does compress →
21
+ sha256 → presign → direct-to-R2 PUT → `/assets/process` → wait-until-ready.
22
+ - **Image URLs** → `getTransformUrl({ sha }, { format: "webp", width })`. The width MUST be on
23
+ `TRANSFORM_WIDTHS` or the edge answers **400**.
24
+ - **Video URLs** → `getAssetUrl({ sha }, "video")` after `setTenantId(id)`. The path segment is
25
+ **base36** (`tenant 12 → /c/v/…`); a decimal prefix 404s.
26
+
27
+ ## The four things that bite hardest
28
+
29
+ 1. **`presets` decides what exists forever.** Omit it and you get `original` only. Ask for
30
+ `["thumb"]` and the bytes you PUT are *not* retrievable. A variant not requested at the FIRST
31
+ ingest cannot be added later once the cleanup job reaps `raw/`.
32
+ 2. **The `amk_rt_*` key is server-only.** The browser talks to *your* route; your server talks to
33
+ aquienpz. A runtime key in a client bundle is a write key to a paid platform.
34
+ 3. **The PUT goes browser → R2 directly, so R2 answers the CORS preflight.** An origin missing from
35
+ the bucket policy cannot be fixed in this SDK, in your app, or in `storefront_origins`. Symptom:
36
+ `R2 PUT failed: network error` with every earlier step green.
37
+ 4. **Video is not image.** `/assets/process` filters video presets to
38
+ `{poster, video, aiproxy, probe}` — `original` is silently dropped — and a video finalizes
39
+ ASYNCHRONOUSLY: the call answers `{ assetId, status: "processing" }` and a Cloud Run Job flips it
40
+ to `ready` 1–2 min later, so `processAndWait` needs a `timeoutMs` of at least `300_000`.
41
+
42
+ ## Related packages
43
+
44
+ | Package | Job |
45
+ |---|---|
46
+ | `@nitida/asset-client` | URL builders + preset tables. No network, no key. |
47
+ | `@nitida/asset-compressor-web` | Browser image compression (worker → OffscreenCanvas → WebP). |
48
+ | `@aquienpz/asset-uploader-web` | Per-file transport: multipart, resume via IndexedDB, progress. |