Skip to content
Back to skills

Brand Memory

ASecurity

Create, read, update, validate and audit the project's brand file, .atelier/brand.json (studio, product, voice, hex palette, font stacks, logos, social handles, deploy target, motion and surface tokens). Use when starting a design workflow, running /brand-init, /brand-get, /brand-set or /brand-audit, changing a brand color or font, or checking brand.json against its schema.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 13, 2026
designgoshellbashnodegitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 13, 2026

npx -y skills add EthanY33/atelier --skill brand-memory --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Brand Memory?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Brand Memory
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ethany33-brand-memory/badge)](https://www.skillsdirectory.com/skills/ethany33-brand-memory)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: brand-memory
description: Create, read, update, validate and audit the project's brand file, .atelier/brand.json (studio, product, voice, hex palette, font stacks, logos, social handles, deploy target, motion and surface tokens). Use when starting a design workflow, running /brand-init, /brand-get, /brand-set or /brand-audit, changing a brand color or font, or checking brand.json against its schema.
---

Skills such as design-token-sync and og-card-generator read this file. Every command works on `<root>/.atelier/brand.json`, with `--root` defaulting to the current directory.

## Run

```bash
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" brand init --studio goneIdle --product TideWane \
  --voice "atmospheric, mysterious" --bg "#110f1b" --accent "#67e8f9" \
  --body-font "Silkscreen, 'Courier New', monospace" --display-font "Space Grotesk, sans-serif" \
  --deploy cloudflare-pages
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" brand get palette.bg --raw
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" brand set palette.terra "#e07a5f"
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" brand set brand.voice "calm, precise"
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" brand audit
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" brand validate
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" brand path
```

JS API (synchronous). The module path is passed as an argument and turned into a file URL, so the same line works on Windows, macOS and Linux. This one sets the accent in `./.atelier/brand.json` and prints what the audit still misses:

```bash
node --input-type=module -e "const { pathToFileURL } = await import('node:url'); const m = await import(pathToFileURL(process.argv[1]).href); const cfg = m.setPath(m.loadBrand(process.cwd()), 'palette.accent', '#67e8f9'); m.saveBrand(process.cwd(), cfg); console.log(m.auditBrand(cfg).missing);" "${CLAUDE_SKILL_DIR}/index.mjs"
```

- `loadBrand(root)` returns the validated object. Throws when the file is missing, is not valid JSON, or fails the schema; `err.code` is `BRAND_NOT_FOUND`, `BRAND_INVALID` (with `err.errors`) or `BRAND_UNREADABLE`, and the message names the file. A UTF-8 or UTF-16 BOM is accepted.
- `saveBrand(root, cfg)` returns nothing. Validates first and throws `invalid brand config: ...` (`BRAND_INVALID`) without writing; otherwise writes 2-space JSON plus a trailing newline, or throws `BRAND_UNWRITABLE`.
- `initBrand(root, { studio, bodyFont, primaryColor, product?, voice?, accent?, displayFont?, monoFont?, deployTarget?, withSchema?, overwrite? })` validates everything, writes once, returns the object. `voice` may be a comma string. `accent` goes to `palette.accent`, `deployTarget` to `deploy.target`. `withSchema: true` adds `$schema`. `overwrite: false` throws `BRAND_EXISTS` if the file exists.
- `validateBrand(cfg)` returns `{ valid, errors }` without touching disk.
- `getPath(obj, 'a.b')` returns the value or `undefined`; follows own properties only.
- `setPath(obj, 'a.b', value)` returns a deep clone with the value set and creates missing objects. Throws on `__proto__`, `constructor` or `prototype` segments, empty segments, and non-index keys inside arrays.
- `auditBrand(cfg)` returns `{ missing: string[] }`.
- `brandFilePath(root)`, `BRAND_SCHEMA_URL`, `runCli(argv, { cwd, stdout, stderr })` (returns the exit code).

## Options

- Every command: `--root <dir>` (project root that holds `.atelier/`, default the current directory), `-h`/`--help` (prints usage, exits 0).
- `init`: `--studio`, `--product`, `--voice <a,b,c>`, `--bg <hex>`, `--accent <hex>`, `--body-font`, `--display-font`, `--mono-font`, `--deploy <target>`, `--force`. Omitted `--studio`, `--bg`, `--body-font` default to the root folder name, `#111111` and `system-ui, sans-serif`, and the output says so. Refuses to overwrite without `--force`. Writes a `$schema` key for editor autocomplete.
- `get <path>`: `--raw` prints a string without JSON quotes.
- `set <path> <value>`: the value is parsed as JSON when it is valid JSON, else kept as a string. String fields keep numbers as text, array fields (`brand.voice`, `deploy.stores`) split a comma list, palette values may omit `#`. Extra words are joined with spaces.
- `audit`, `validate`: `--json`.
- Quote `#hex` values in a shell. For a value starting with `-`, use `--body-font=-apple-system,...` or `set -- <path> <value>`.

## Output

Schema (`${CLAUDE_PLUGIN_ROOT}/schemas/brand.schema.json`, JSON Schema 2020-12). Required: `brand.studio`, at least one `palette` color, `typography.body`.

- `palette.<key>`: `#rgb`, `#rrggbb` or `#rrggbbaa`; keys start with a letter (letters, digits, `_`, `-`).
- `typography.body|display|mono`: CSS font stacks, max 300 chars, no `< > { } ;`, backslash or control characters.
- `brand.voice`, `deploy.stores`: string arrays. `deploy.stores` items: `steam`, `itch`, `apple`, `google`.
- `deploy.target`: `cloudflare-pages`, `netlify`, `github-pages`, `vercel` or `custom`.
- Optional `logos.mark|wordmark`, `social.<platform>`, `motion`, `surfaces`, `targets`.

Validation messages name the dotted property and list allowed values, e.g. `deploy.target: "firebase" is not allowed (allowed: cloudflare-pages, ...)`.

Audit checks: `brand.product`, `brand.voice`, `typography.display`, `logos.mark`, `logos.wordmark`, `social`, `deploy.target`.

## Exit codes

- `0`: success, including `--help`. `audit` always exits 0.
- `1`: `validate` found errors (including malformed JSON).
- `2`: usage error, missing or unreadable brand.json, `get` on an unset path, or `init`/`set` rejected (file exists, invalid value, forbidden path).

## Notes

- `/brand-init`: ask for studio, product, voice (2 to 4 adjectives), background hex, accent hex, body font stack, optional display font, and deploy target, then run one `brand init` with all of them and relay its audit. Ask before passing `--force`.
- `/brand-set`: `brand set <path> <value>`, then report the echoed value or the validation message.
- `get`, `set` and `audit` read the file without validating it, so `set` can repair an invalid field (the result is validated before it is saved). `validate` and `loadBrand` enforce the schema; `audit` adds a note when the file does not pass.

Files in this skill

  • SKILL.md6 KB
  • index.mjs25.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.