# @skenora/resources

Provider-based resource discovery, policy, caching, integrity checks, and
lifetime management for Skenora.

```bash
pnpm add @skenora/resources
```

Entry points:

| Import                            | Purpose                                                   |
| --------------------------------- | --------------------------------------------------------- |
| `@skenora/resources`              | `ResourceManager`, provider contracts, discovery helpers  |
| `@skenora/resources/workspace`    | workspace provider and shared resource context            |
| `@skenora/resources/http`         | opt-in allowlisted HTTPS provider                         |
| `@skenora/resources/memory`       | in-memory Blob resources                                  |
| `@skenora/resources/particles`    | opt-in particle textures, metadata discovery and provider |
| `@skenora/resources/presentation` | opt-in softbox HDR, surface maps and metadata discovery   |

Resource providers translate persistent locators into acquired bytes.
`ResourceScope` owns temporary Blob URLs and must be disposed. Network loading
is unavailable until the host explicitly installs and authorizes an HTTP or
custom provider.

See the [resource guide](https://github.com/zhangjiadi225/skenora/blob/main/docs/RESOURCES.md).

## Scene-plan bindings and leases

Scene-plan inputs use logical references. The host supplies an already
authorized `ResourceBinding` and may validate it against the plan's kind,
media type, and SHA-256 integrity requirement without performing I/O:

```ts
import {
  createResourceBindingScope,
  createResourceBindingTable,
} from "@skenora/resources";

const bindings = createResourceBindingTable(
  [{ assetRef: "chair", asset: authorizedAsset }],
  [{ assetRef: "chair", kind: "model" }],
);
const bindingScope = createResourceBindingScope(resources, bindings);
const chair = bindingScope.acquire("chair");
const resolved = await chair.resource;

// Keep the lease until Runtime projection has completed.
bindingScope.dispose();
```

`ModelVisibleResourceDescriptor` and
`toModelVisibleResourceDescriptor()` expose only an opaque logical reference
and safe metadata. They omit provider ids, sources, paths, URLs, thumbnails,
credentials, and Blob URLs. The existing `ResourceDescriptor` remains
available for trusted host/provider code for backward compatibility; callers
must project it before returning data to a model.

`ResourceBindingScope` creates one child `ResourceScope` per lease. Releasing
a lease or disposing the binding scope delegates to the existing
reference-counted cache and Blob URL cleanup. Authorization, downloads,
imports, and workspace writes remain outside this package.

## Original presentation assets

The opt-in presentation entry provides six CC0-1.0 resources: `softbox-v1`,
`daylight-window-v1`, `technical-strip-v1` analytical HDR environments,
`oak-color-v1`, `stone-color-v1` original color maps and `fabric-normal-v1`
original linear normal map. Metadata discovery downloads nothing. The generator
is `scripts/generate-presentation-resources.mjs`; generated byte hashes are
checked on acquisition. Explicit resource provider installation is required.
