npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@odla-ai/brand

v0.7.2

Published

Conversational brand-book builder for odla apps — document/image uploads onto odla-db files, agent-driven color exploration and palette proposals with human-gated approval, a zero-dep OKLCH/WCAG color engine, and a token compiler that turns an approved br

Readme

@odla-ai/brand

A conversational brand-book builder for odla apps — document and image uploads onto odla-db file storage, agent-driven color exploration with human-gated palette proposals, a zero-dependency OKLCH/WCAG color engine, and a token compiler that turns an approved brand book into @odla-ai/ui design tokens. The conversation itself rides @odla-ai/chat.

npm i @odla-ai/brand

Agentic experiment. This package is built and maintained by AI agents working from bounded runbooks with human review. Review its documented guarantees before relying on it.

Ask the runbooks first. odla's operational procedures live in a database, not in this file: npx @odla-ai/cli runbook ask "<question>" returns the current steps, and unlike anything written here it cannot be out of date. Use it before searching the web or working from memory. This README and the JSDoc in the shipped .d.ts are the version-matched API reference; a runbook is the procedure. Most tasks need an answer from both.

The shape

The package is a schema + rules + an agent skill + a color engine + a token compiler + a route factory — not a service you run.

  • Proposals are the human checkpoint. Brand direction, image/logo choices, typography, voice, and colors stay proposals in the conversation. Palette candidates are the executable path today: the agent explores them with deterministic OKLCH/WCAG math and writes an open brand_proposal. A human approves, rejects, or requests a revision before any palette effect. The agent skill has no resolution tool: both propose_palette and update_section park open proposals. A current book member who is also a direct Clerk app owner/co-owner posts the exact reviewed snapshot to the guarded route. It consumes one central human_exact brand.approve use and atomically writes the effect plus an immutable brand_approval_receipt. The central receipt names the exact Registry app incarnation, so an approval from a purged project cannot resolve content in a same-id replacement. Review clients must retain one mutation id for each exact proposal digest + accepted/rejected decision across pending requests and retries. Proposal author names must come from a Registry-owned principal projection; mutable chat participants and raw ids are not identity presentation.

  • Vision happens through a semantic bridge. view_asset asks the trusted host for bytes by asset id and returns image/PDF blocks inside the tool result when the model supports them. The rules-scoped agent credential cannot read raw files, mint signed URLs, or write brand_* rows. There is no raw or signed-URL fallback. Message attachment ids are revalidated against the exact live Brand book before they enter the prompt; every facet proposal may preserve the source asset's immutable byte snapshot.

  • Brand child writes are worker-mediated. CEL permits members to read their sections, palettes, proposals, and approval receipts, but all writes are closed. createBrandRoutes owns guarded human decisions and proxies private multipart uploads, short-lived signed downloads, and human effects. Agent tools call only the host-provided BrandAgentBridge operations in BRAND_AGENT_PROFILE.

  • The upload surface is intentionally narrow. Raster PNG/JPEG/GIF/WebP and PDF inputs are supported. SVG active content and binary font files are not; typography remains an exact, reviewable family/style proposal.

  • Tokens compile to the @odla-ai/ui contract. compileBrandTokens maps swatch roles onto --ui-* names — always emitting every required token plus the accent-composing derived set, so a scoped preview island never keeps stale root composites — and renderTokensCss emits theme-structured CSS (light, dark, invert). Dark is derived algorithmically and contrast re-tuned per token. A reviewed typography proposal may also carry bounded tokenOverrides; those --ui-* component and layout values are validated, stored with the approved section, and compiled into both published token maps.

  • Zero runtime dependencies. The db client is injected structurally (a real @odla-ai/db AdminDb satisfies BrandDb); @odla-ai/ai is a types-only optional peer.

  • Claude Designs are a first-class input. A design exported from Claude as standalone HTML is a self-contained bundle: a loader plus a base64 asset manifest plus the real document. Upload it as a design asset and the worker parses it in the same write — the --ui-* tokens it declares (resolved through var() chains, so a vendored theme re-keyed by a brand block yields the brand's real colors), its typefaces, its configurable props, and its heading outline — and stores that digest on the row. design is the only kind whose content type may be text/html, and text/html is refused for every other kind.

Quick start

import { createBrandRoutes, BRAND_SCHEMA, brandRules } from "@odla-ai/brand";
import { init } from "@odla-ai/db";

const db = init({ appId, adminToken, endpoint });

// One-time provisioning: POST BRAND_SCHEMA to /schema and brandRules() to
// /admin/rules (or use the brandIntegration descriptor with the odla CLI).

const routes = createBrandRoutes({
  db,
  appId,
  authorize: verifyDirectCaller,
  // Read-only: exact brand/brand.read/audience/app-incarnation assertion.
  authorizeDiscussionReferences: verifyDiscussionReferenceAssertion,
  // Optional test/edge fetch; it receives only a Brand-minted private URL.
  fetchPrivateAsset: fetch,
  authorizeCapability: verifyCurrentHumanAppOwner,
  consumeHumanExact: async (input) =>
    (await appsForBearer(input.req).consumeHumanExactAuthority(
      input.appId,
      {
        capability: input.capability,
        projectCapability: input.projectCapability,
        effect: input.effect,
        resource: input.resource,
        actionDigest: input.actionDigest,
        consumptionIdempotencyKey: input.consumptionIdempotencyKey,
      },
    )).receipt,
  verifySourceAssetSnapshot: verifyPrivateObjectExactly,
});

export default {
  async fetch(req: Request): Promise<Response> {
    return (await routes(req)) ?? new Response("not found", { status: 404 });
  },
};

GET /api/brand/discussion-references?q=… searches only books on the asserted principal's current roster and their live assets, palettes, proposals, and receipts. Supplying kind + id performs exact lookup and returns no item unless that row still exists in the named book. Returned links use stable odla-ref=brand:kind/book-id[/resource-id] identities; the destination calls parseBrandDiscussionReference to select the book and review surface. Each projection includes a bounded product-authored summary, status, and destination for people and read-only agent tools. Registry assertions bind the exact brand product, brand.read, current canonical endpoint audience, app incarnation, environment, and principal; an agent assertion also binds its manager and live grant revision. The host must set its current ODLA_APP_INCARNATION and fail closed on a mismatch. This assertion cannot authorize proposal resolution or any other Brand mutation.

Palette projections additionally carry at most 24 validated semantic roles, normalized #rrggbb colors, and bounded optional names so Discussion can use the shared @odla-ai/ui PaletteStrip without reconstructing brand state. An assertion-authorized exact lookup may request inspect=asset-content&kind=brand:asset&id=…. Brand resolves the linked row, mints its own short-lived private-object URL, and returns only bounded PNG, JPEG, GIF, WebP, or PDF bytes—never the URL or a separate object path, storage id, app id, or book id. Only the already-discovered canonical reference id crosses the boundary. It validates type and magic, size, and SHA-256, then reloads both membership and the exact linked asset row after I/O. SVG, malformed, spoofed, changed, unsupported, and over-budget assets fail closed. Returned bytes carry untrusted_project_material taint for the hosted inference boundary; the native link remains navigation only and human proposal approval is unchanged.

Resolve a proposal from a human review UI with one stable mutation id. Send back exactly the proposal snapshot that UI rendered; a stale or concurrently resolved snapshot answers 409, while an identical retry returns the original receipt with duplicate: true.

await fetch(`/api/brand/books/${book.id}/proposals/${proposal.id}/resolve`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    mutationId: crypto.randomUUID(),
    resolution: "accepted", // or "rejected"
    reviewedProposal: proposal,
    note: "Approved in palette review",
  }),
});

Wire the agent by attaching brandSkill to a persona (or let the chat-agent worker route a brandBotTrigger dispatch into dispatchBrandTurn):

import { createBrandPersona, supportsBrandVision } from "@odla-ai/brand";

const spec = inference.catalog[model];
const persona = createBrandPersona({
  model,
  brand: {
    db: rulesScopedAgentDb,
    bookId,
    self: { selfId: botId, kind: "bot" },
    agentDbBinding: { principalId: botId, credentialRef },
    agentJobId: jobId,
    agentBridge,
    authorizeCapability: verifyLiveAgentGrant,
    resolvePrincipals: resolveSafeDirectoryProjection,
    visionInToolResults: supportsBrandVision(spec),
  },
});
const run = await runAgent(inference, persona, { input: userMessage });

Compile anywhere, including a host that wants only the zero-dependency token engine. The ./tokens subpath does not load the agent, routes, or brand-book schema:

import { compileBrandTokens, renderTokensCss } from "@odla-ai/brand/tokens";

const { light, dark, warnings } = compileBrandTokens({ swatches });
const css = renderTokensCss(light, { dark }); // :root / [data-theme="dark"] / media guard

Designs

Three resolutions of the same design, because none of them is right for every reader:

| surface | what it gives you | |---|---| | GET /books/:id/assets/:aid/preview | the design itself, proxied under Content-Security-Policy: sandbox allow-scripts. No allow-same-origin, so it renders in an opaque origin and cannot touch the host app's session, storage, or DOM. Proxied rather than redirected to storage, so the sandbox header is the app's to set. | | GET /books/:id/assets/:aid/design | the stored digest as JSON — tokens, fonts, colors, props, outline, inventory. Kilobytes, not megabytes. | | read_design, read_design_source, propose_palette_from_design | the agent's view: the digest as prose, a window of the real template for porting exact markup, and the design's own --ui-* declarations read back into a palette proposal. |

compileBrandTokens runs brand book → --ui-*. A design authored on the @odla-ai/ui contract arrives with that mapping's output already filled in, so swatchesFromDesignTokens inverts it — built from the forward map's own role table, so the two cannot drift. Only literal opaque colors convert; a token left as color-mix(…), a translucent rgba(…), or an unresolved var(…) is reported, not guessed at, because a fabricated hex would silently poison the contrast math. The result is an open brand_proposal a human resolves through the same guarded route as any other.

For work outside the conversation, the CLI unpacks a bundle to disk with no account and no network:

npx odla-ai brand design unpack "Built Not Found Capital.html" --out site/design
#   index.html     the design, asset references rewritten to real files — runs offline
#   assets/        every embedded font, image, and script, decoded (gzip inflated)
#   pages/         nested page bundles, for multi-page designs
#   digest.json    tokens, props, outline, inventory
#   tokens.css     the design's tokens as an @odla-ai/ui theme sheet (light + dark)

That directory is what you point a coding agent at: real files it can read and diff, instead of one megabyte of base64.

Authority and asset contract

  • Install BRAND_AGENT_PROFILE: agents receive only brand.read and brand.edit, and may create proposals, record analysis, and read bounded asset content only through semantic host operations. Deny raw Brand writes, raw file reads, signing, and admin credentials.
  • createBrandRoutes requires all security seams. authorize derives the actor from a verified bearer; authorizeCapability revalidates current app ownership; consumeHumanExact consumes the exact reviewed action; and verifySourceAssetSnapshot revalidates private path, ETag, size, media type, and SHA-256 immediately before approval. The returned authority receipt must carry the current 32-character app incarnation and is stored losslessly with the Brand decision.
  • 409 means the review or authority conflicted, 410 means its authority or source is gone, and registry/storage/network outages remain opaque 500s. Definite identity or object mismatches fail closed.