@bezel-labs/bezel-kit 0.8.1 → 0.10.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/README.md CHANGED
@@ -45,6 +45,8 @@ bezel init [options] # create a bezel.json for this project
45
45
  bezel build [options] # generate the outputs (default command)
46
46
  bezel install-mcp [--client] # connect an AI coding tool to the Bezel MCP
47
47
  bezel install-skills [--client] # teach an AI coding tool how to work with Bezel
48
+ bezel diff [--json] # local edits not in Bezel yet; --json prints them for a push
49
+ bezel sync [--discard-local-edits] # apply tokens fetched by the Bezel MCP (.bezel/sync.json)
48
50
  ```
49
51
 
50
52
  `init` writes the config so you don't have to author it by hand, picking defaults from
@@ -75,7 +77,6 @@ the project link rather than the build:
75
77
  - `projectId` (optional) — the Bezel project this repo is linked to (a UUID).
76
78
  - `version` (recommended, default `latest`) — the tokens the Bezel MCP fetches: `latest`
77
79
  for the project's latest snapshot, or a published semver like `1.4.0`.
78
-
79
80
  Both are read only by the Bezel MCP and ignored by `build`.
80
81
 
81
82
  ```json
@@ -86,6 +87,24 @@ Both are read only by the Bezel MCP and ignored by `build`.
86
87
  }
87
88
  ```
88
89
 
90
+ ### Lockfile — `design-tokens-lock.json`
91
+
92
+ Like `package-lock.json` next to `package.json`: `bezel.json` says which project and version
93
+ to track, and `design-tokens-lock.json` records what was resolved — the exact tokens and the
94
+ project revision this repo last synced or pushed. Commit it together with
95
+ `design-tokens.json` and never edit it. `bezel sync` is the only thing that writes it.
96
+
97
+ - **Sync:** the Bezel MCP's `get-design-tokens-file` returns the lockfile text. Your agent
98
+ writes it to `.bezel/sync.json` (gitignored) and runs `bezel sync`, which writes the
99
+ lockfile and `design-tokens.json` together and rebuilds. It exits with code 2 instead of
100
+ dropping edits Bezel does not have (`--discard-local-edits` overrides).
101
+ - **Push:** `bezel diff --json` prints your edits as JSON Patch operations with `test`
102
+ guards — the same format the Bezel app saves with — so only the edits travel. After the
103
+ Bezel MCP saves them, a sync moves the lockfile to the new revision (your edits are
104
+ already in Bezel, so the sync keeps them and pulls in anything others changed).
105
+
106
+ `revision` in `bezel.json` (0.9.0) moved into the lockfile; `bezel init` removes the old key.
107
+
89
108
  Generated outputs live in their own directory because `build` overwrites them without
90
109
  asking and adds them to `.gitignore` — keeping them out of a hand-written `src/styles`
91
110
  means a generic name like `variables.css` can never clobber a file you wrote.
@@ -135,11 +154,14 @@ Either re-export `design-tokens.json` from Bezel, or pin the old key in `bezel.j
135
154
 
136
155
  - **Core (`.`):** `tokensToCss`, `emitCss`, `resolveCssOptions`, `getContexts`,
137
156
  `formatContextsModule`, `getFonts`, `formatFontsModule`, the `DEFAULT_CONTEXTS` /
138
- `DEFAULT_NAME_EXTENSION` defaults, `AGENT_SKILL`, plus the related types.
157
+ `DEFAULT_NAME_EXTENSION` defaults, `AGENT_SKILL`, the lockfile helpers (`buildLockfile`,
158
+ `parseLockfile`, `serializeLockfile`, `isPatchApplied`, ...), plus the
159
+ related types.
139
160
  - **Agent skill (`./agent-skill`):** just `AGENT_SKILL` — the `bezel` skill text (`SKILL.md`,
140
161
  references, the `AGENTS.md` block, and a short summary for MCP `instructions`).
141
162
  - **Node (`./node`):** everything above, plus `generateVariablesCss`, `resolveOptions`,
142
- `initConfig`, and the `DEFAULT_OUTPUT_DIR` / `DEFAULT_CONFIG_FILE` defaults.
163
+ `initConfig`, `diffTokens`, `syncFromStaging`, and the
164
+ `DEFAULT_OUTPUT_DIR` / `DEFAULT_CONFIG_FILE` defaults.
143
165
 
144
166
  ## Development
145
167
 
@@ -25,14 +25,14 @@ __export(agent_skill_exports, {
25
25
  module.exports = __toCommonJS(agent_skill_exports);
26
26
  var AGENT_SKILL = {
27
27
  name: "bezel",
28
- description: "Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app and using the Bezel MCP tools.",
28
+ description: "Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.",
29
29
  files: {
30
- "SKILL.md": '---\nname: bezel\ndescription: Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app and using the Bezel MCP tools.\n---\n\n# Bezel in this repository\n\nBezel is a design-token platform. Designers maintain the tokens in the Bezel app; this repo holds an exported copy and generates CSS from it with `@bezel-labs/bezel-kit`.\n\n```\nBezel app (cloud, source of truth)\n -> design-tokens.json DTCG file at the repo root, exported from Bezel\n -> bezel build reads bezel.json for options and output paths\n -> variables.css one CSS scope per context (:root, .dark, .light, ...)\n contexts.ts, fonts.ts optional generated TypeScript modules\n```\n\nNothing in this repo pushes back to Bezel. A change that must survive the next sync belongs in the Bezel app.\n\n## Hard rules\n\n1. Never edit a generated file. They start with `/* Generated by bezel \u2014 do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo\'s package manager runner). Confirm the outputs were rewritten before finishing.\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `"includeAll": true`. Adding a token without an `exportName` produces no variable.\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\n6. Local edits to `design-tokens.json` are overwritten by the next sync from Bezel. Tell the user when a change should be made in the Bezel app instead, and never silently sync over their local edits.\n\n## The tokens file\n\n`design-tokens.json` follows the W3C Design Tokens (DTCG) format. Every token is an object with a `$type` and one `$value` per context:\n\n```json\n"semantic": {\n "color": {\n "primary": {\n "$type": "color",\n "$root": { "$value": "{base.color.green.500}" },\n "dark": { "$value": { "colorSpace": "oklch", "components": [0.85, 0.16, 152] } },\n "$extensions": { "com.bezel.app": { "exportName": ["primary", "ring"] } }\n }\n }\n}\n```\n\n- Context keys (`$root`, `dark`, `light`, or whatever `bezel.json` `contexts` lists) sit inside the token. `$root` is the base; other contexts only need the values that differ.\n- `$value` is either a literal (DTCG color, dimension, font family, ...) or a reference like `{base.color.green.500}`. References are resolved to literal values in the generated CSS.\n- `$extensions["com.bezel.app"].exportName` is the list of CSS variable names the token emits. One token can emit several (`foreground`, `card-foreground`). An empty list means no variable.\n- Groups (`base`, `semantic`, `color`, ...) are plain nesting with no `$type`.\n\n## What to do for common requests\n\n| Request | Edit | Then |\n|---|---|---|\n| Change a color, size, radius, or font value | The token\'s `$value` in the right context key (`$root` for every mode, `dark` for dark mode only) | Rebuild |\n| A value should differ in dark mode | Add or edit the `dark` key on that token | Rebuild |\n| New CSS variable | Add a token with `$type`, `$root.$value`, and an `exportName` (or reference an existing token) | Rebuild |\n| Rename a CSS variable | Change the `exportName` entry; update every consumer of the old `--name` | Rebuild |\n| New theme or brand context | Add the context to `bezel.json` `contexts` (name -> selector) and add that key to the tokens that differ | Rebuild |\n| Change where files are generated | Edit `variablesOutput` / `contextsOutput` / `fontsOutput` in `bezel.json`; update the CSS import | Rebuild, delete the old outputs |\n| "Pull the latest tokens" / "sync from Bezel" | See the next section | Rebuild |\n\nFind the token for an existing variable by searching `design-tokens.json` for its name inside an `exportName` array.\n\n## Pulling the latest tokens from Bezel\n\n`bezel.json` `projectId` and `version` (`"latest"` or a published semver) say which Bezel project and snapshot this repo tracks.\n\nWith the Bezel MCP connected: call `get-design-tokens-file` with that `projectId` and `version`, write the returned `content` string to `design-tokens.json` verbatim (no reformatting), then rebuild. The `sync-project` prompt walks through this, including linking a project when `projectId` is missing. Never pick a project or version yourself; ask when it is ambiguous.\n\nWithout the MCP: ask the user to download `design-tokens.json` from the project in the Bezel app and replace the file at the repo root, then rebuild.\n\nWarn before overwriting a `design-tokens.json` that has local edits.\n\n## With the Bezel MCP connected\n\nPrefer small, targeted calls over reading the whole tokens file:\n\n- `get-project-manifest` first: groups, counts, types, contexts, no values.\n- `query-tokens` to find tokens by group, type, name, or `exportName`; `get-token-by-path` for one token with every context value.\n- `get-token-bundle` for a curated set per task (`theming-setup`, `button`, `card`, `form`, ...).\n- `export-tokens` and `get-framework-overrides` to generate CSS, JS/TS objects, or Tailwind / shadcn / Mantine config from tokens.\n- `contrast-check`, `color-convert`, `color-ramp`, `unit-convert` for deterministic math instead of estimating.\n- `design-review` to check a component description against the tokens.\n\nSee `references/mcp-tools.md` for the full list and `references/bezel-json.md` for every config field.\n\n## Setting up a repo that is not on Bezel yet\n\nRun the `setup-project` tool (or the `/mcp__bezel__setup-project` prompt) and follow it; it installs `@bezel-labs/bezel-kit`, writes `bezel.json`, fetches the tokens, builds, and wires the CSS import. Do not improvise the steps.\n',
31
- "references/bezel-json.md": '# bezel.json reference\n\n`bezel.json` lives at the repo root (or the working directory `bezel build` runs in). `bezel build` loads it automatically; `bezel init` writes it. The tokens input is always `design-tokens.json` in that same directory and is not configurable.\n\n| Field | Default | Used by | Meaning |\n|---|---|---|---|\n| `projectId` | none | MCP | UUID of the Bezel project this repo tracks. Set with `npx bezel init --project <uuid>`. |\n| `version` | `"latest"` | MCP | Which tokens snapshot to fetch: `"latest"` or a published semver such as `"1.4.0"`. Set with `--tokens-version`. |\n| `variablesOutput` | `"src/bezel/variables.css"` | build | Generated CSS file. Import this from the app entry. |\n| `contextsOutput` | none | build | When set, writes a TypeScript module exporting `CONTEXTS` (the context names). |\n| `fontsOutput` | none | build | When set, writes a TypeScript module exporting `FONTS` (web fonts derived from the tokens). |\n| `contexts` | `{ "$root": ":root", "dark": ".dark", "light": ".light" }` | build | Context name -> CSS selector. The first entry is the base context and is emitted in full; the rest are override-only blocks. |\n| `colorFormat` | `"oklch"` | build | `"oklch"` or `"hex"`. |\n| `dimensionUnit` | `"preserve"` | build | `"preserve"` keeps authored units; `"rem"` converts `px` to `rem`. |\n| `nameExtension` | `"com.bezel.app"` | build | The `$extensions` key that holds `exportName`. Only change for files exported before the 0.3.0 rename. |\n| `includeAll` | `false` | build | Also emit a variable for every token without an `exportName`, named by its kebab-cased path (`--base-color-primary-500`). |\n| `write` | `true` | build | `false` returns the CSS without writing files (programmatic use). |\n| `gitignore` | `true` | build | Maintain a `# bezel:start` ... `# bezel:end` block in `.gitignore` listing the generated outputs. |\n| `gitignorePath` | `".gitignore"` | build | Which `.gitignore` to manage. |\n| `cwd` | process cwd | build | Base directory paths resolve against. |\n\n`projectId` and `version` are ignored by `bezel build`; everything else is ignored by the MCP.\n\n## CLI\n\n```\nbezel init [--project <uuid>] [--tokens-version <v>] [--dir <path>] ... create or update bezel.json\nbezel build [--stdout] [--no-gitignore] ... generate the outputs (default command)\nbezel install-mcp [--client <name>] connect an AI coding tool to the Bezel MCP\nbezel install-skills [--client <name>] [--no-agents-md] install this skill into the repo\n```\n\n`bezel init` on an existing `bezel.json` with `--project` or `--tokens-version` updates only those keys. Any other re-run leaves the file alone unless `--force` is passed, which agents must not do.\n',
32
- "references/mcp-tools.md": "# Bezel MCP quick reference\n\nRemote server at `https://mcp.bezel.new/mcp` (Streamable HTTP, OAuth). The server returns data and instructions; the coding agent performs every local file edit and command. Project-scoped tools take the `projectId` from `bezel.json` or from `find-project`.\n\n## Guided workflows\n\n| Tool / prompt | Use |\n|---|---|\n| `setup-project` (tool and prompt) | Resumable setup: install bezel-kit, link a project, write `bezel.json`, fetch tokens, build, wire the CSS import, optional Crystal live preview. |\n| `sync-project` (prompt) | Refresh `design-tokens.json` from the linked project and version, then rebuild. |\n| `safe-usage-guide` (prompt) | Context-budget rules: manifest first, targeted queries, cite token paths. |\n| `manifest-first-workflow`, `context-resolution` (prompts) | Recommended reading order and how contexts resolve. |\n| `get-agent-guide` (tool) | Returns this skill's text when the repo has no local copy. |\n\n## Discovery\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `find-project` | `query?` | All owned projects (name + id), or one project resolved from a name or UUID. |\n| `get-project-manifest` | `projectId` | Groups, token counts, types, contexts. No values. Call this first. |\n\n## Repo sync\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `get-design-tokens-file` | `projectId`, `version?` | The exact `design-tokens.json` content to write to disk, plus project name and version. Unknown version -> list of available versions. |\n\n## Reading tokens\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `query-tokens` | `projectId`, `groupPath?`, `tokenType?`, `search?`, `exportName?`, `contextKey?`, `resolveAliases?` | Filtered tokens. |\n| `get-token-by-path` | `projectId`, `tokenPath`, `contextKey?`, `resolveAliases?` | One token with every context value and alias detail. |\n| `get-token-bundle` | `projectId`, `intent` | Curated set: `theming-setup`, `button`, `card`, `input`, `form`, `auth-page`, `dashboard-shell`. |\n| `get-project-contexts` | `projectId` | Context groups and values (theme modes, platforms, brands). |\n| `resolve-context` | `projectId`, `contextGroup`, `contextValue` | Canonical context value or a structured error. |\n\n## Generating code\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `export-tokens` | `projectId`, `format` (`css-variables`, `js-object`, `ts-object`), filters, `prefix?`, `includeAll?` | Generated code with aliases resolved. |\n| `get-framework-overrides` | `projectId`, `framework` (`tailwind`, `shadcn`, `mantine`), `version?`, filters | Framework config derived from the tokens. |\n\n## Color and unit math (deterministic)\n\n| Tool | Parameters |\n|---|---|\n| `contrast-check` | `foreground`, `background` -> WCAG ratio, grade, recommendations |\n| `color-convert` | `color`, `targetFormat`, `manipulation?`, `mixColor?` |\n| `color-ramp` | `baseColor`, `steps`, `endColor?`, `colorSpace?` |\n| `unit-convert` | `value`, `fromUnit`, `toUnit`, `rootFontSize?`, `parentFontSize?` |\n\n## Review and history\n\n| Tool | Parameters |\n|---|---|\n| `design-review` | `projectId`, `componentDescription`, `tokenPathsUsed?`, `contextKey?` |\n| `get-chat-history` | `projectId` |\n| `search-chat-history` | `projectId`, `query` |\n\n## Resources\n\n- `bezel://projects`: your projects with ids and names.\n- `bezel://agent-guide`: this skill's text.\n"
30
+ "SKILL.md": '---\nname: bezel\ndescription: Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.\n---\n\n# Bezel in this repository\n\nBezel is a design-token platform. Designers maintain the tokens in the Bezel app; this repo holds an exported copy and generates CSS from it with `@bezel-labs/bezel-kit`.\n\n```\nBezel app (cloud, source of truth)\n -> design-tokens.json DTCG file at the repo root, exported from Bezel\n design-tokens-lock.json what was last synced or pushed (tokens + revision); commit it\n -> bezel build reads bezel.json for options and output paths\n -> variables.css one CSS scope per context (:root, .dark, .light, ...)\n contexts.ts, fonts.ts optional generated TypeScript modules\n```\n\nThe Bezel app stays the source of truth. Local edits to `design-tokens.json` reach Bezel only when they are pushed through the Bezel MCP, after a preview and the user\'s explicit yes (see "Pushing changes back to Bezel"); until then the next sync replaces them.\n\n## Hard rules\n\n1. Never edit a generated file. They start with `/* Generated by bezel \u2014 do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo\'s package manager runner). Confirm the outputs were rewritten before finishing.\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `"includeAll": true`. Adding a token without an `exportName` produces no variable.\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\n6. Local edits to `design-tokens.json` are not in Bezel until they are pushed. `npx bezel diff` lists them. Never sync over them silently: offer to push them first. Pushing means `npx bezel diff --json`, `preview-design-tokens-push` with its operations, showing the `confirmationPrompt` word for word, `push-design-tokens` only after the user says yes, then a sync. Never push without that confirmation, and never push from a "sync" or "pull" request.\n7. Never write or edit `design-tokens-lock.json`, and never write a synced `design-tokens.json` from MCP output yourself. Only `bezel sync` writes them, after every sync and every push, so the two files always agree. Commit both files together.\n\n## The tokens file\n\n`design-tokens.json` follows the W3C Design Tokens (DTCG) format. Every token is an object with a `$type` and one `$value` per context:\n\n```json\n"semantic": {\n "color": {\n "primary": {\n "$type": "color",\n "$root": { "$value": "{base.color.green.500}" },\n "dark": { "$value": { "colorSpace": "oklch", "components": [0.85, 0.16, 152] } },\n "$extensions": { "com.bezel.app": { "exportName": ["primary", "ring"] } }\n }\n }\n}\n```\n\n- Context keys (`$root`, `dark`, `light`, or whatever `bezel.json` `contexts` lists) sit inside the token. `$root` is the base; other contexts only need the values that differ.\n- `$value` is either a literal (DTCG color, dimension, font family, ...) or a reference like `{base.color.green.500}`. References are resolved to literal values in the generated CSS.\n- `$extensions["com.bezel.app"].exportName` is the list of CSS variable names the token emits. One token can emit several (`foreground`, `card-foreground`). An empty list means no variable.\n- Groups (`base`, `semantic`, `color`, ...) are plain nesting with no `$type`.\n\n## What to do for common requests\n\n| Request | Edit | Then |\n|---|---|---|\n| Change a color, size, radius, or font value | The token\'s `$value` in the right context key (`$root` for every mode, `dark` for dark mode only) | Rebuild |\n| A value should differ in dark mode | Add or edit the `dark` key on that token | Rebuild |\n| New CSS variable | Add a token with `$type`, `$root.$value`, and an `exportName` (or reference an existing token) | Rebuild |\n| Rename a CSS variable | Change the `exportName` entry; update every consumer of the old `--name` | Rebuild |\n| New theme or brand context | Add the context to `bezel.json` `contexts` (name -> selector) and add that key to the tokens that differ | Rebuild |\n| Change where files are generated | Edit `variablesOutput` / `contextsOutput` / `fontsOutput` in `bezel.json`; update the CSS import | Rebuild, delete the old outputs |\n| "Pull the latest tokens" / "sync from Bezel" | See the next section | `bezel sync` rebuilds |\n| "Push my changes to Bezel" / save local token edits back | Nothing by hand; follow "Pushing changes back to Bezel" | Sync, which updates the lockfile |\n\nFind the token for an existing variable by searching `design-tokens.json` for its name inside an `exportName` array.\n\n## Pulling the latest tokens from Bezel\n\n`bezel.json` `projectId` and `version` (`"latest"` or a published semver) say which Bezel project and snapshot this repo tracks. `design-tokens-lock.json` records the tokens and project revision this repo last synced or pushed, like `package-lock.json` next to `package.json`. Only `bezel sync` writes it.\n\nWith the Bezel MCP connected:\n\n1. Run `npx bezel diff`. If it lists local edits, stop and offer to push them first (next section). A lockfile problem it reports is fixed by this sync.\n2. Call `get-design-tokens-file` with that `projectId` and `version`. Write the returned `lockfileContent` exactly as returned to `.bezel/sync.json`.\n3. Run `npx bezel sync`. It checks the staged file, writes `design-tokens-lock.json` and then `design-tokens.json`, deletes the staged file, and rebuilds.\n - Exit code 2 means `design-tokens.json` has edits Bezel does not have. Show the message and offer to push them. Use `npx bezel sync --discard-local-edits` only when the user says to drop them.\n - `unknown command "sync"` means the installed `@bezel-labs/bezel-kit` is too old. Update it first.\n\nThe `sync-project` prompt walks through this, including linking a project when `projectId` is missing. Never pick a project or version yourself; ask when it is ambiguous.\n\nWithout the MCP: ask the user to download `design-tokens.json` from the project in the Bezel app and replace the file at the repo root, then rebuild. Pushing later needs a lockfile, so sync through the MCP when it becomes available.\n\n## Pushing changes back to Bezel\n\nNeeds the Bezel MCP. A push sends only your edits, as JSON Patch operations, the same way the Bezel app saves. Bezel applies them to the project\'s working tokens (`latest`) and keeps changes others made in the meantime. Publishing a version still happens in the Bezel app.\n\n1. Run `npx bezel diff --json`. `"ok": false` prints what to do (every lockfile problem is fixed by a sync). `"operations": []` means nothing to push.\n2. If `bezel.json` `version` is a semver, tell the user the push updates the working project, not that pinned release.\n3. Call `preview-design-tokens-push` with `projectId`, the printed `operations` and `baseRevision` unchanged, and `version` as `trackedVersion`. It saves nothing.\n4. `invalid` or `blocked`: report and stop (`blocked` is a plan limit). `conflict`: the listed tokens changed in Bezel too; follow `nextStep`. `no-changes` with `alreadyApplied`: an earlier push saved these edits but the sync after it did not run; sync now. Themes the edits use that the project lacks are added by the push (`addedContexts`).\n5. `ready`: show `confirmationPrompt` to the user word for word and wait. Do not push on silence, a question, or a different request.\n6. After an explicit yes, call `push-design-tokens` with the same `projectId`, `operations`, and `baseRevision`.\n7. A push is not finished until the repo is synced. Sync as in the previous section, steps 2 and 3: `get-design-tokens-file`, write `lockfileContent` to `.bezel/sync.json`, run `npx bezel sync`. Your edits are already in Bezel, so the sync keeps them, pulls in anything others changed, and moves the lockfile to the new revision. Then tell the user to commit `design-tokens.json` and `design-tokens-lock.json` together.\n\nThe `push-project` prompt walks through this.\n\n## With the Bezel MCP connected\n\nPrefer small, targeted calls over reading the whole tokens file:\n\n- `get-project-manifest` first: groups, counts, types, contexts, no values.\n- `query-tokens` to find tokens by group, type, name, or `exportName`; `get-token-by-path` for one token with every context value.\n- `get-token-bundle` for a curated set per task (`theming-setup`, `button`, `card`, `form`, ...).\n- `export-tokens` and `get-framework-overrides` to generate CSS, JS/TS objects, or Tailwind / shadcn / Mantine config from tokens.\n- `contrast-check`, `color-convert`, `color-ramp`, `unit-convert` for deterministic math instead of estimating.\n- `design-review` to check a component description against the tokens.\n\nSee `references/mcp-tools.md` for the full list and `references/bezel-json.md` for every config field.\n\n## Setting up a repo that is not on Bezel yet\n\nRun the `setup-project` tool (or the `/mcp__bezel__setup-project` prompt) and follow it; it installs `@bezel-labs/bezel-kit`, writes `bezel.json`, fetches the tokens, builds, and wires the CSS import. Do not improvise the steps.\n',
31
+ "references/bezel-json.md": '# bezel.json reference\n\n`bezel.json` lives at the repo root (or the working directory `bezel build` runs in). `bezel build` loads it automatically; `bezel init` writes it. The tokens input is always `design-tokens.json` in that same directory and is not configurable.\n\n| Field | Default | Used by | Meaning |\n|---|---|---|---|\n| `projectId` | none | MCP | UUID of the Bezel project this repo tracks. Set with `npx bezel init --project <uuid>`. |\n| `version` | `"latest"` | MCP | Which tokens snapshot to fetch: `"latest"` or a published semver such as `"1.4.0"`. Set with `--tokens-version`. |\n| `variablesOutput` | `"src/bezel/variables.css"` | build | Generated CSS file. Import this from the app entry. |\n| `contextsOutput` | none | build | When set, writes a TypeScript module exporting `CONTEXTS` (the context names). |\n| `fontsOutput` | none | build | When set, writes a TypeScript module exporting `FONTS` (web fonts derived from the tokens). |\n| `contexts` | `{ "$root": ":root", "dark": ".dark", "light": ".light" }` | build | Context name -> CSS selector. The first entry is the base context and is emitted in full; the rest are override-only blocks. |\n| `colorFormat` | `"oklch"` | build | `"oklch"` or `"hex"`. |\n| `dimensionUnit` | `"preserve"` | build | `"preserve"` keeps authored units; `"rem"` converts `px` to `rem`. |\n| `nameExtension` | `"com.bezel.app"` | build | The `$extensions` key that holds `exportName`. Only change for files exported before the 0.3.0 rename. |\n| `includeAll` | `false` | build | Also emit a variable for every token without an `exportName`, named by its kebab-cased path (`--base-color-primary-500`). |\n| `write` | `true` | build | `false` returns the CSS without writing files (programmatic use). |\n| `gitignore` | `true` | build | Maintain a `# bezel:start` ... `# bezel:end` block in `.gitignore` listing the generated outputs. |\n| `gitignorePath` | `".gitignore"` | build | Which `.gitignore` to manage. |\n| `cwd` | process cwd | build | Base directory paths resolve against. |\n\n`projectId` and `version` are ignored by `bezel build`; everything else is ignored by the MCP. The synced revision lives in `design-tokens-lock.json`, not here.\n\n## design-tokens-lock.json\n\nCommitted next to `design-tokens.json`, like `package-lock.json` next to `package.json`. It records the tokens and project revision this repo last synced or pushed: `lockfileVersion`, `projectId`, `version`, `revision`, and `tokens`. `bezel diff` compares `design-tokens.json` against it to find local edits. Only `bezel sync` writes it, after every sync and every push; never edit it. `bezel init --project` deletes a lockfile that belongs to a different project.\n\n## CLI\n\n```\nbezel init [--project <uuid>] [--tokens-version <v>] [--dir <path>] ... create or update bezel.json\nbezel build [--stdout] [--no-gitignore] ... generate the outputs (default command)\nbezel install-mcp [--client <name>] connect an AI coding tool to the Bezel MCP\nbezel install-skills [--client <name>] [--no-agents-md] install this skill into the repo\nbezel diff [--json] local edits vs design-tokens-lock.json (--json: JSON Patch operations for a push)\nbezel sync [--discard-local-edits] apply .bezel/sync.json: write the lockfile and design-tokens.json, then build\n```\n\n`bezel sync` exits with code 2 when `design-tokens.json` has edits Bezel does not have; other problems exit with 1.\n\n`bezel init` on an existing `bezel.json` with `--project` or `--tokens-version` updates only those keys. Any other re-run leaves the file alone unless `--force` is passed, which agents must not do.\n',
32
+ "references/mcp-tools.md": "# Bezel MCP quick reference\n\nRemote server at `https://mcp.bezel.new/mcp` (Streamable HTTP, OAuth). The server returns data and instructions; the coding agent performs every local file edit and command. Project-scoped tools take the `projectId` from `bezel.json` or from `find-project`.\n\n## Guided workflows\n\n| Tool / prompt | Use |\n|---|---|\n| `setup-project` (tool and prompt) | Resumable setup: install bezel-kit, link a project, write `bezel.json`, fetch tokens, build, wire the CSS import, optional Crystal live preview. |\n| `sync-project` (prompt) | Refresh `design-tokens.json` and `design-tokens-lock.json` from the linked project and version through `bezel sync`. Offers to push local edits first instead of overwriting them. |\n| `push-project` (prompt) | Diff, preview, confirm with the user, and push the repo's token edits to the linked project, then sync so `design-tokens-lock.json` moves to the new revision. |\n| `safe-usage-guide` (prompt) | Context-budget rules: manifest first, targeted queries, cite token paths. |\n| `manifest-first-workflow`, `context-resolution` (prompts) | Recommended reading order and how contexts resolve. |\n| `get-agent-guide` (tool) | Returns this skill's text when the repo has no local copy. |\n\n## Discovery\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `find-project` | `query?` | All owned projects (name + id), or one project resolved from a name or UUID. |\n| `get-project-manifest` | `projectId` | Groups, token counts, types, contexts. No values. Call this first. |\n\n## Repo sync\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `get-design-tokens-file` | `projectId`, `version?` | `lockfileContent`: the full `design-tokens-lock.json` text (tokens + `revision`). Write it to `.bezel/sync.json` and run `npx bezel sync`. Unknown version -> list of available versions. |\n| `preview-design-tokens-push` | `projectId`, `operations`, `baseRevision?`, `trackedVersion?` | Checks the edits from `npx bezel diff --json` against the working tokens: plan-limit problems, `conflict` (tokens edited here and in Bezel), themes the edits add (`addedContexts`), `behind` when Bezel moved on (those changes are kept), and a `confirmationPrompt` to show verbatim. Saves nothing. |\n| `push-design-tokens` | `projectId`, `operations`, `baseRevision?` | Saves the previewed edits as a new revision. Call only after the user confirms the preview. Returns the new `revision`. Sync right after it so the lockfile moves to that revision. |\n\n## Reading tokens\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `query-tokens` | `projectId`, `groupPath?`, `tokenType?`, `search?`, `exportName?`, `contextKey?`, `resolveAliases?` | Filtered tokens. |\n| `get-token-by-path` | `projectId`, `tokenPath`, `contextKey?`, `resolveAliases?` | One token with every context value and alias detail. |\n| `get-token-bundle` | `projectId`, `intent` | Curated set: `theming-setup`, `button`, `card`, `input`, `form`, `auth-page`, `dashboard-shell`. |\n| `get-project-contexts` | `projectId` | Context groups and values (theme modes, platforms, brands). |\n| `resolve-context` | `projectId`, `contextGroup`, `contextValue` | Canonical context value or a structured error. |\n\n## Generating code\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `export-tokens` | `projectId`, `format` (`css-variables`, `js-object`, `ts-object`), filters, `prefix?`, `includeAll?` | Generated code with aliases resolved. |\n| `get-framework-overrides` | `projectId`, `framework` (`tailwind`, `shadcn`, `mantine`), `version?`, filters | Framework config derived from the tokens. |\n\n## Color and unit math (deterministic)\n\n| Tool | Parameters |\n|---|---|\n| `contrast-check` | `foreground`, `background` -> WCAG ratio, grade, recommendations |\n| `color-convert` | `color`, `targetFormat`, `manipulation?`, `mixColor?` |\n| `color-ramp` | `baseColor`, `steps`, `endColor?`, `colorSpace?` |\n| `unit-convert` | `value`, `fromUnit`, `toUnit`, `rootFontSize?`, `parentFontSize?` |\n\n## Review and history\n\n| Tool | Parameters |\n|---|---|\n| `design-review` | `projectId`, `componentDescription`, `tokenPathsUsed?`, `contextKey?` |\n| `get-chat-history` | `projectId` |\n| `search-chat-history` | `projectId`, `query` |\n\n## Resources\n\n- `bezel://projects`: your projects with ids and names.\n- `bezel://agent-guide`: this skill's text.\n"
33
33
  },
34
- agentsMdBlock: '## Bezel design tokens\n\n- `design-tokens.json` at the repo root is the source for every design token. Edit it to change a color, size, font, or radius, or to add a CSS variable (add an `exportName` under `$extensions["com.bezel.app"]`).\n- Files under the Bezel output folder (`variablesOutput`, `contextsOutput`, `fontsOutput` in `bezel.json`; `src/bezel/` by default) are generated. Never edit them; they are overwritten on every build.\n- After changing `design-tokens.json` or `bezel.json`, run `npm run tokens` (or `npx bezel build`) and check the outputs were rewritten.\n- Dark mode and other contexts are keys inside each token (`$root`, `dark`, `light`). Add a value under the context key instead of writing a CSS override.\n- The Bezel app is the source of truth. Local token edits are replaced by the next sync (`get-design-tokens-file` via the Bezel MCP, or a download from the app), so tell the user when a change should be made in Bezel.\n- Never run `bezel init --force`; it discards the existing `bezel.json`. Use `--project` or `--tokens-version` to update a single key.\n- Full guidance: the `bezel` skill in `.claude/skills/bezel/SKILL.md` or `.agents/skills/bezel/SKILL.md`.',
35
- summary: 'Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app and using the Bezel MCP tools.\n\n## Hard rules\n\n1. Never edit a generated file. They start with `/* Generated by bezel \u2014 do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo\'s package manager runner). Confirm the outputs were rewritten before finishing.\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `"includeAll": true`. Adding a token without an `exportName` produces no variable.\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\n6. Local edits to `design-tokens.json` are overwritten by the next sync from Bezel. Tell the user when a change should be made in the Bezel app instead, and never silently sync over their local edits.'
34
+ agentsMdBlock: '## Bezel design tokens\n\n- `design-tokens.json` at the repo root is the source for every design token. Edit it to change a color, size, font, or radius, or to add a CSS variable (add an `exportName` under `$extensions["com.bezel.app"]`).\n- Files under the Bezel output folder (`variablesOutput`, `contextsOutput`, `fontsOutput` in `bezel.json`; `src/bezel/` by default) are generated. Never edit them; they are overwritten on every build.\n- After changing `design-tokens.json` or `bezel.json`, run `npm run tokens` (or `npx bezel build`) and check the outputs were rewritten.\n- Dark mode and other contexts are keys inside each token (`$root`, `dark`, `light`). Add a value under the context key instead of writing a CSS override.\n- The Bezel app is the source of truth. `design-tokens-lock.json` records what was last synced or pushed; never edit it, and commit it together with `design-tokens.json`. `npx bezel diff` lists local edits that are not in Bezel yet.\n- Sync through the Bezel MCP: write `get-design-tokens-file`\'s `lockfileContent` to `.bezel/sync.json`, then run `npx bezel sync` (it writes both files and refuses to drop unpushed edits). To push, run `npx bezel diff --json`, call `preview-design-tokens-push` with its operations, show the confirmation prompt word for word, call `push-design-tokens` only after the user says yes, then sync to update the lockfile.\n- Never run `bezel init --force`; it discards the existing `bezel.json`. Use `--project` or `--tokens-version` to update a single key.\n- Full guidance: the `bezel` skill in `.claude/skills/bezel/SKILL.md` or `.agents/skills/bezel/SKILL.md`.',
35
+ summary: 'Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.\n\n## Hard rules\n\n1. Never edit a generated file. They start with `/* Generated by bezel \u2014 do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo\'s package manager runner). Confirm the outputs were rewritten before finishing.\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `"includeAll": true`. Adding a token without an `exportName` produces no variable.\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\n6. Local edits to `design-tokens.json` are not in Bezel until they are pushed. `npx bezel diff` lists them. Never sync over them silently: offer to push them first. Pushing means `npx bezel diff --json`, `preview-design-tokens-push` with its operations, showing the `confirmationPrompt` word for word, `push-design-tokens` only after the user says yes, then a sync. Never push without that confirmation, and never push from a "sync" or "pull" request.\n7. Never write or edit `design-tokens-lock.json`, and never write a synced `design-tokens.json` from MCP output yourself. Only `bezel sync` writes them, after every sync and every push, so the two files always agree. Commit both files together.'
36
36
  };
37
37
  // Annotate the CommonJS export names for ESM import in node:
38
38
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent-skill.ts"],"sourcesContent":["/* Generated from skill/bezel by scripts/build-agent-skill.mjs — do not edit by hand. */\n\n/** The Bezel agent skill, embedded so it can be installed into a repo or served by the Bezel MCP. */\nexport interface AgentSkill {\n /** Skill name; also the folder name under `.claude/skills` or `.agents/skills`. */\n name: string\n /** Frontmatter description: when the skill applies. */\n description: string\n /** Skill files keyed by path relative to the skill folder (`SKILL.md`, `references/...`). */\n files: Record<string, string>\n /** Markdown placed inside the managed block of AGENTS.md. */\n agentsMdBlock: string\n /** Description plus the hard rules, sized for an MCP `instructions` field. */\n summary: string\n}\n\nexport const AGENT_SKILL: AgentSkill = {\n name: \"bezel\",\n description: \"Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app and using the Bezel MCP tools.\",\n files: {\n \"SKILL.md\": \"---\\nname: bezel\\ndescription: Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app and using the Bezel MCP tools.\\n---\\n\\n# Bezel in this repository\\n\\nBezel is a design-token platform. Designers maintain the tokens in the Bezel app; this repo holds an exported copy and generates CSS from it with `@bezel-labs/bezel-kit`.\\n\\n```\\nBezel app (cloud, source of truth)\\n -> design-tokens.json DTCG file at the repo root, exported from Bezel\\n -> bezel build reads bezel.json for options and output paths\\n -> variables.css one CSS scope per context (:root, .dark, .light, ...)\\n contexts.ts, fonts.ts optional generated TypeScript modules\\n```\\n\\nNothing in this repo pushes back to Bezel. A change that must survive the next sync belongs in the Bezel app.\\n\\n## Hard rules\\n\\n1. Never edit a generated file. They start with `/* Generated by bezel — do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo's package manager runner). Confirm the outputs were rewritten before finishing.\\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `\\\"includeAll\\\": true`. Adding a token without an `exportName` produces no variable.\\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\\n6. Local edits to `design-tokens.json` are overwritten by the next sync from Bezel. Tell the user when a change should be made in the Bezel app instead, and never silently sync over their local edits.\\n\\n## The tokens file\\n\\n`design-tokens.json` follows the W3C Design Tokens (DTCG) format. Every token is an object with a `$type` and one `$value` per context:\\n\\n```json\\n\\\"semantic\\\": {\\n \\\"color\\\": {\\n \\\"primary\\\": {\\n \\\"$type\\\": \\\"color\\\",\\n \\\"$root\\\": { \\\"$value\\\": \\\"{base.color.green.500}\\\" },\\n \\\"dark\\\": { \\\"$value\\\": { \\\"colorSpace\\\": \\\"oklch\\\", \\\"components\\\": [0.85, 0.16, 152] } },\\n \\\"$extensions\\\": { \\\"com.bezel.app\\\": { \\\"exportName\\\": [\\\"primary\\\", \\\"ring\\\"] } }\\n }\\n }\\n}\\n```\\n\\n- Context keys (`$root`, `dark`, `light`, or whatever `bezel.json` `contexts` lists) sit inside the token. `$root` is the base; other contexts only need the values that differ.\\n- `$value` is either a literal (DTCG color, dimension, font family, ...) or a reference like `{base.color.green.500}`. References are resolved to literal values in the generated CSS.\\n- `$extensions[\\\"com.bezel.app\\\"].exportName` is the list of CSS variable names the token emits. One token can emit several (`foreground`, `card-foreground`). An empty list means no variable.\\n- Groups (`base`, `semantic`, `color`, ...) are plain nesting with no `$type`.\\n\\n## What to do for common requests\\n\\n| Request | Edit | Then |\\n|---|---|---|\\n| Change a color, size, radius, or font value | The token's `$value` in the right context key (`$root` for every mode, `dark` for dark mode only) | Rebuild |\\n| A value should differ in dark mode | Add or edit the `dark` key on that token | Rebuild |\\n| New CSS variable | Add a token with `$type`, `$root.$value`, and an `exportName` (or reference an existing token) | Rebuild |\\n| Rename a CSS variable | Change the `exportName` entry; update every consumer of the old `--name` | Rebuild |\\n| New theme or brand context | Add the context to `bezel.json` `contexts` (name -> selector) and add that key to the tokens that differ | Rebuild |\\n| Change where files are generated | Edit `variablesOutput` / `contextsOutput` / `fontsOutput` in `bezel.json`; update the CSS import | Rebuild, delete the old outputs |\\n| \\\"Pull the latest tokens\\\" / \\\"sync from Bezel\\\" | See the next section | Rebuild |\\n\\nFind the token for an existing variable by searching `design-tokens.json` for its name inside an `exportName` array.\\n\\n## Pulling the latest tokens from Bezel\\n\\n`bezel.json` `projectId` and `version` (`\\\"latest\\\"` or a published semver) say which Bezel project and snapshot this repo tracks.\\n\\nWith the Bezel MCP connected: call `get-design-tokens-file` with that `projectId` and `version`, write the returned `content` string to `design-tokens.json` verbatim (no reformatting), then rebuild. The `sync-project` prompt walks through this, including linking a project when `projectId` is missing. Never pick a project or version yourself; ask when it is ambiguous.\\n\\nWithout the MCP: ask the user to download `design-tokens.json` from the project in the Bezel app and replace the file at the repo root, then rebuild.\\n\\nWarn before overwriting a `design-tokens.json` that has local edits.\\n\\n## With the Bezel MCP connected\\n\\nPrefer small, targeted calls over reading the whole tokens file:\\n\\n- `get-project-manifest` first: groups, counts, types, contexts, no values.\\n- `query-tokens` to find tokens by group, type, name, or `exportName`; `get-token-by-path` for one token with every context value.\\n- `get-token-bundle` for a curated set per task (`theming-setup`, `button`, `card`, `form`, ...).\\n- `export-tokens` and `get-framework-overrides` to generate CSS, JS/TS objects, or Tailwind / shadcn / Mantine config from tokens.\\n- `contrast-check`, `color-convert`, `color-ramp`, `unit-convert` for deterministic math instead of estimating.\\n- `design-review` to check a component description against the tokens.\\n\\nSee `references/mcp-tools.md` for the full list and `references/bezel-json.md` for every config field.\\n\\n## Setting up a repo that is not on Bezel yet\\n\\nRun the `setup-project` tool (or the `/mcp__bezel__setup-project` prompt) and follow it; it installs `@bezel-labs/bezel-kit`, writes `bezel.json`, fetches the tokens, builds, and wires the CSS import. Do not improvise the steps.\\n\",\n \"references/bezel-json.md\": \"# bezel.json reference\\n\\n`bezel.json` lives at the repo root (or the working directory `bezel build` runs in). `bezel build` loads it automatically; `bezel init` writes it. The tokens input is always `design-tokens.json` in that same directory and is not configurable.\\n\\n| Field | Default | Used by | Meaning |\\n|---|---|---|---|\\n| `projectId` | none | MCP | UUID of the Bezel project this repo tracks. Set with `npx bezel init --project <uuid>`. |\\n| `version` | `\\\"latest\\\"` | MCP | Which tokens snapshot to fetch: `\\\"latest\\\"` or a published semver such as `\\\"1.4.0\\\"`. Set with `--tokens-version`. |\\n| `variablesOutput` | `\\\"src/bezel/variables.css\\\"` | build | Generated CSS file. Import this from the app entry. |\\n| `contextsOutput` | none | build | When set, writes a TypeScript module exporting `CONTEXTS` (the context names). |\\n| `fontsOutput` | none | build | When set, writes a TypeScript module exporting `FONTS` (web fonts derived from the tokens). |\\n| `contexts` | `{ \\\"$root\\\": \\\":root\\\", \\\"dark\\\": \\\".dark\\\", \\\"light\\\": \\\".light\\\" }` | build | Context name -> CSS selector. The first entry is the base context and is emitted in full; the rest are override-only blocks. |\\n| `colorFormat` | `\\\"oklch\\\"` | build | `\\\"oklch\\\"` or `\\\"hex\\\"`. |\\n| `dimensionUnit` | `\\\"preserve\\\"` | build | `\\\"preserve\\\"` keeps authored units; `\\\"rem\\\"` converts `px` to `rem`. |\\n| `nameExtension` | `\\\"com.bezel.app\\\"` | build | The `$extensions` key that holds `exportName`. Only change for files exported before the 0.3.0 rename. |\\n| `includeAll` | `false` | build | Also emit a variable for every token without an `exportName`, named by its kebab-cased path (`--base-color-primary-500`). |\\n| `write` | `true` | build | `false` returns the CSS without writing files (programmatic use). |\\n| `gitignore` | `true` | build | Maintain a `# bezel:start` ... `# bezel:end` block in `.gitignore` listing the generated outputs. |\\n| `gitignorePath` | `\\\".gitignore\\\"` | build | Which `.gitignore` to manage. |\\n| `cwd` | process cwd | build | Base directory paths resolve against. |\\n\\n`projectId` and `version` are ignored by `bezel build`; everything else is ignored by the MCP.\\n\\n## CLI\\n\\n```\\nbezel init [--project <uuid>] [--tokens-version <v>] [--dir <path>] ... create or update bezel.json\\nbezel build [--stdout] [--no-gitignore] ... generate the outputs (default command)\\nbezel install-mcp [--client <name>] connect an AI coding tool to the Bezel MCP\\nbezel install-skills [--client <name>] [--no-agents-md] install this skill into the repo\\n```\\n\\n`bezel init` on an existing `bezel.json` with `--project` or `--tokens-version` updates only those keys. Any other re-run leaves the file alone unless `--force` is passed, which agents must not do.\\n\",\n \"references/mcp-tools.md\": \"# Bezel MCP quick reference\\n\\nRemote server at `https://mcp.bezel.new/mcp` (Streamable HTTP, OAuth). The server returns data and instructions; the coding agent performs every local file edit and command. Project-scoped tools take the `projectId` from `bezel.json` or from `find-project`.\\n\\n## Guided workflows\\n\\n| Tool / prompt | Use |\\n|---|---|\\n| `setup-project` (tool and prompt) | Resumable setup: install bezel-kit, link a project, write `bezel.json`, fetch tokens, build, wire the CSS import, optional Crystal live preview. |\\n| `sync-project` (prompt) | Refresh `design-tokens.json` from the linked project and version, then rebuild. |\\n| `safe-usage-guide` (prompt) | Context-budget rules: manifest first, targeted queries, cite token paths. |\\n| `manifest-first-workflow`, `context-resolution` (prompts) | Recommended reading order and how contexts resolve. |\\n| `get-agent-guide` (tool) | Returns this skill's text when the repo has no local copy. |\\n\\n## Discovery\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `find-project` | `query?` | All owned projects (name + id), or one project resolved from a name or UUID. |\\n| `get-project-manifest` | `projectId` | Groups, token counts, types, contexts. No values. Call this first. |\\n\\n## Repo sync\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `get-design-tokens-file` | `projectId`, `version?` | The exact `design-tokens.json` content to write to disk, plus project name and version. Unknown version -> list of available versions. |\\n\\n## Reading tokens\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `query-tokens` | `projectId`, `groupPath?`, `tokenType?`, `search?`, `exportName?`, `contextKey?`, `resolveAliases?` | Filtered tokens. |\\n| `get-token-by-path` | `projectId`, `tokenPath`, `contextKey?`, `resolveAliases?` | One token with every context value and alias detail. |\\n| `get-token-bundle` | `projectId`, `intent` | Curated set: `theming-setup`, `button`, `card`, `input`, `form`, `auth-page`, `dashboard-shell`. |\\n| `get-project-contexts` | `projectId` | Context groups and values (theme modes, platforms, brands). |\\n| `resolve-context` | `projectId`, `contextGroup`, `contextValue` | Canonical context value or a structured error. |\\n\\n## Generating code\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `export-tokens` | `projectId`, `format` (`css-variables`, `js-object`, `ts-object`), filters, `prefix?`, `includeAll?` | Generated code with aliases resolved. |\\n| `get-framework-overrides` | `projectId`, `framework` (`tailwind`, `shadcn`, `mantine`), `version?`, filters | Framework config derived from the tokens. |\\n\\n## Color and unit math (deterministic)\\n\\n| Tool | Parameters |\\n|---|---|\\n| `contrast-check` | `foreground`, `background` -> WCAG ratio, grade, recommendations |\\n| `color-convert` | `color`, `targetFormat`, `manipulation?`, `mixColor?` |\\n| `color-ramp` | `baseColor`, `steps`, `endColor?`, `colorSpace?` |\\n| `unit-convert` | `value`, `fromUnit`, `toUnit`, `rootFontSize?`, `parentFontSize?` |\\n\\n## Review and history\\n\\n| Tool | Parameters |\\n|---|---|\\n| `design-review` | `projectId`, `componentDescription`, `tokenPathsUsed?`, `contextKey?` |\\n| `get-chat-history` | `projectId` |\\n| `search-chat-history` | `projectId`, `query` |\\n\\n## Resources\\n\\n- `bezel://projects`: your projects with ids and names.\\n- `bezel://agent-guide`: this skill's text.\\n\"\n },\n agentsMdBlock: \"## Bezel design tokens\\n\\n- `design-tokens.json` at the repo root is the source for every design token. Edit it to change a color, size, font, or radius, or to add a CSS variable (add an `exportName` under `$extensions[\\\"com.bezel.app\\\"]`).\\n- Files under the Bezel output folder (`variablesOutput`, `contextsOutput`, `fontsOutput` in `bezel.json`; `src/bezel/` by default) are generated. Never edit them; they are overwritten on every build.\\n- After changing `design-tokens.json` or `bezel.json`, run `npm run tokens` (or `npx bezel build`) and check the outputs were rewritten.\\n- Dark mode and other contexts are keys inside each token (`$root`, `dark`, `light`). Add a value under the context key instead of writing a CSS override.\\n- The Bezel app is the source of truth. Local token edits are replaced by the next sync (`get-design-tokens-file` via the Bezel MCP, or a download from the app), so tell the user when a change should be made in Bezel.\\n- Never run `bezel init --force`; it discards the existing `bezel.json`. Use `--project` or `--tokens-version` to update a single key.\\n- Full guidance: the `bezel` skill in `.claude/skills/bezel/SKILL.md` or `.agents/skills/bezel/SKILL.md`.\",\n summary: \"Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app and using the Bezel MCP tools.\\n\\n## Hard rules\\n\\n1. Never edit a generated file. They start with `/* Generated by bezel — do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo's package manager runner). Confirm the outputs were rewritten before finishing.\\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `\\\"includeAll\\\": true`. Adding a token without an `exportName` produces no variable.\\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\\n6. Local edits to `design-tokens.json` are overwritten by the next sync from Bezel. Tell the user when a change should be made in the Bezel app instead, and never silently sync over their local edits.\",\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,OAAO;AAAA,IACL,YAAY;AAAA,IACZ,4BAA4B;AAAA,IAC5B,2BAA2B;AAAA,EAC7B;AAAA,EACA,eAAe;AAAA,EACf,SAAS;AACX;","names":[]}
1
+ {"version":3,"sources":["../src/agent-skill.ts"],"sourcesContent":["/* Generated from skill/bezel by scripts/build-agent-skill.mjs — do not edit by hand. */\n\n/** The Bezel agent skill, embedded so it can be installed into a repo or served by the Bezel MCP. */\nexport interface AgentSkill {\n /** Skill name; also the folder name under `.claude/skills` or `.agents/skills`. */\n name: string\n /** Frontmatter description: when the skill applies. */\n description: string\n /** Skill files keyed by path relative to the skill folder (`SKILL.md`, `references/...`). */\n files: Record<string, string>\n /** Markdown placed inside the managed block of AGENTS.md. */\n agentsMdBlock: string\n /** Description plus the hard rules, sized for an MCP `instructions` field. */\n summary: string\n}\n\nexport const AGENT_SKILL: AgentSkill = {\n name: \"bezel\",\n description: \"Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.\",\n files: {\n \"SKILL.md\": \"---\\nname: bezel\\ndescription: Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.\\n---\\n\\n# Bezel in this repository\\n\\nBezel is a design-token platform. Designers maintain the tokens in the Bezel app; this repo holds an exported copy and generates CSS from it with `@bezel-labs/bezel-kit`.\\n\\n```\\nBezel app (cloud, source of truth)\\n -> design-tokens.json DTCG file at the repo root, exported from Bezel\\n design-tokens-lock.json what was last synced or pushed (tokens + revision); commit it\\n -> bezel build reads bezel.json for options and output paths\\n -> variables.css one CSS scope per context (:root, .dark, .light, ...)\\n contexts.ts, fonts.ts optional generated TypeScript modules\\n```\\n\\nThe Bezel app stays the source of truth. Local edits to `design-tokens.json` reach Bezel only when they are pushed through the Bezel MCP, after a preview and the user's explicit yes (see \\\"Pushing changes back to Bezel\\\"); until then the next sync replaces them.\\n\\n## Hard rules\\n\\n1. Never edit a generated file. They start with `/* Generated by bezel — do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo's package manager runner). Confirm the outputs were rewritten before finishing.\\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `\\\"includeAll\\\": true`. Adding a token without an `exportName` produces no variable.\\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\\n6. Local edits to `design-tokens.json` are not in Bezel until they are pushed. `npx bezel diff` lists them. Never sync over them silently: offer to push them first. Pushing means `npx bezel diff --json`, `preview-design-tokens-push` with its operations, showing the `confirmationPrompt` word for word, `push-design-tokens` only after the user says yes, then a sync. Never push without that confirmation, and never push from a \\\"sync\\\" or \\\"pull\\\" request.\\n7. Never write or edit `design-tokens-lock.json`, and never write a synced `design-tokens.json` from MCP output yourself. Only `bezel sync` writes them, after every sync and every push, so the two files always agree. Commit both files together.\\n\\n## The tokens file\\n\\n`design-tokens.json` follows the W3C Design Tokens (DTCG) format. Every token is an object with a `$type` and one `$value` per context:\\n\\n```json\\n\\\"semantic\\\": {\\n \\\"color\\\": {\\n \\\"primary\\\": {\\n \\\"$type\\\": \\\"color\\\",\\n \\\"$root\\\": { \\\"$value\\\": \\\"{base.color.green.500}\\\" },\\n \\\"dark\\\": { \\\"$value\\\": { \\\"colorSpace\\\": \\\"oklch\\\", \\\"components\\\": [0.85, 0.16, 152] } },\\n \\\"$extensions\\\": { \\\"com.bezel.app\\\": { \\\"exportName\\\": [\\\"primary\\\", \\\"ring\\\"] } }\\n }\\n }\\n}\\n```\\n\\n- Context keys (`$root`, `dark`, `light`, or whatever `bezel.json` `contexts` lists) sit inside the token. `$root` is the base; other contexts only need the values that differ.\\n- `$value` is either a literal (DTCG color, dimension, font family, ...) or a reference like `{base.color.green.500}`. References are resolved to literal values in the generated CSS.\\n- `$extensions[\\\"com.bezel.app\\\"].exportName` is the list of CSS variable names the token emits. One token can emit several (`foreground`, `card-foreground`). An empty list means no variable.\\n- Groups (`base`, `semantic`, `color`, ...) are plain nesting with no `$type`.\\n\\n## What to do for common requests\\n\\n| Request | Edit | Then |\\n|---|---|---|\\n| Change a color, size, radius, or font value | The token's `$value` in the right context key (`$root` for every mode, `dark` for dark mode only) | Rebuild |\\n| A value should differ in dark mode | Add or edit the `dark` key on that token | Rebuild |\\n| New CSS variable | Add a token with `$type`, `$root.$value`, and an `exportName` (or reference an existing token) | Rebuild |\\n| Rename a CSS variable | Change the `exportName` entry; update every consumer of the old `--name` | Rebuild |\\n| New theme or brand context | Add the context to `bezel.json` `contexts` (name -> selector) and add that key to the tokens that differ | Rebuild |\\n| Change where files are generated | Edit `variablesOutput` / `contextsOutput` / `fontsOutput` in `bezel.json`; update the CSS import | Rebuild, delete the old outputs |\\n| \\\"Pull the latest tokens\\\" / \\\"sync from Bezel\\\" | See the next section | `bezel sync` rebuilds |\\n| \\\"Push my changes to Bezel\\\" / save local token edits back | Nothing by hand; follow \\\"Pushing changes back to Bezel\\\" | Sync, which updates the lockfile |\\n\\nFind the token for an existing variable by searching `design-tokens.json` for its name inside an `exportName` array.\\n\\n## Pulling the latest tokens from Bezel\\n\\n`bezel.json` `projectId` and `version` (`\\\"latest\\\"` or a published semver) say which Bezel project and snapshot this repo tracks. `design-tokens-lock.json` records the tokens and project revision this repo last synced or pushed, like `package-lock.json` next to `package.json`. Only `bezel sync` writes it.\\n\\nWith the Bezel MCP connected:\\n\\n1. Run `npx bezel diff`. If it lists local edits, stop and offer to push them first (next section). A lockfile problem it reports is fixed by this sync.\\n2. Call `get-design-tokens-file` with that `projectId` and `version`. Write the returned `lockfileContent` exactly as returned to `.bezel/sync.json`.\\n3. Run `npx bezel sync`. It checks the staged file, writes `design-tokens-lock.json` and then `design-tokens.json`, deletes the staged file, and rebuilds.\\n - Exit code 2 means `design-tokens.json` has edits Bezel does not have. Show the message and offer to push them. Use `npx bezel sync --discard-local-edits` only when the user says to drop them.\\n - `unknown command \\\"sync\\\"` means the installed `@bezel-labs/bezel-kit` is too old. Update it first.\\n\\nThe `sync-project` prompt walks through this, including linking a project when `projectId` is missing. Never pick a project or version yourself; ask when it is ambiguous.\\n\\nWithout the MCP: ask the user to download `design-tokens.json` from the project in the Bezel app and replace the file at the repo root, then rebuild. Pushing later needs a lockfile, so sync through the MCP when it becomes available.\\n\\n## Pushing changes back to Bezel\\n\\nNeeds the Bezel MCP. A push sends only your edits, as JSON Patch operations, the same way the Bezel app saves. Bezel applies them to the project's working tokens (`latest`) and keeps changes others made in the meantime. Publishing a version still happens in the Bezel app.\\n\\n1. Run `npx bezel diff --json`. `\\\"ok\\\": false` prints what to do (every lockfile problem is fixed by a sync). `\\\"operations\\\": []` means nothing to push.\\n2. If `bezel.json` `version` is a semver, tell the user the push updates the working project, not that pinned release.\\n3. Call `preview-design-tokens-push` with `projectId`, the printed `operations` and `baseRevision` unchanged, and `version` as `trackedVersion`. It saves nothing.\\n4. `invalid` or `blocked`: report and stop (`blocked` is a plan limit). `conflict`: the listed tokens changed in Bezel too; follow `nextStep`. `no-changes` with `alreadyApplied`: an earlier push saved these edits but the sync after it did not run; sync now. Themes the edits use that the project lacks are added by the push (`addedContexts`).\\n5. `ready`: show `confirmationPrompt` to the user word for word and wait. Do not push on silence, a question, or a different request.\\n6. After an explicit yes, call `push-design-tokens` with the same `projectId`, `operations`, and `baseRevision`.\\n7. A push is not finished until the repo is synced. Sync as in the previous section, steps 2 and 3: `get-design-tokens-file`, write `lockfileContent` to `.bezel/sync.json`, run `npx bezel sync`. Your edits are already in Bezel, so the sync keeps them, pulls in anything others changed, and moves the lockfile to the new revision. Then tell the user to commit `design-tokens.json` and `design-tokens-lock.json` together.\\n\\nThe `push-project` prompt walks through this.\\n\\n## With the Bezel MCP connected\\n\\nPrefer small, targeted calls over reading the whole tokens file:\\n\\n- `get-project-manifest` first: groups, counts, types, contexts, no values.\\n- `query-tokens` to find tokens by group, type, name, or `exportName`; `get-token-by-path` for one token with every context value.\\n- `get-token-bundle` for a curated set per task (`theming-setup`, `button`, `card`, `form`, ...).\\n- `export-tokens` and `get-framework-overrides` to generate CSS, JS/TS objects, or Tailwind / shadcn / Mantine config from tokens.\\n- `contrast-check`, `color-convert`, `color-ramp`, `unit-convert` for deterministic math instead of estimating.\\n- `design-review` to check a component description against the tokens.\\n\\nSee `references/mcp-tools.md` for the full list and `references/bezel-json.md` for every config field.\\n\\n## Setting up a repo that is not on Bezel yet\\n\\nRun the `setup-project` tool (or the `/mcp__bezel__setup-project` prompt) and follow it; it installs `@bezel-labs/bezel-kit`, writes `bezel.json`, fetches the tokens, builds, and wires the CSS import. Do not improvise the steps.\\n\",\n \"references/bezel-json.md\": \"# bezel.json reference\\n\\n`bezel.json` lives at the repo root (or the working directory `bezel build` runs in). `bezel build` loads it automatically; `bezel init` writes it. The tokens input is always `design-tokens.json` in that same directory and is not configurable.\\n\\n| Field | Default | Used by | Meaning |\\n|---|---|---|---|\\n| `projectId` | none | MCP | UUID of the Bezel project this repo tracks. Set with `npx bezel init --project <uuid>`. |\\n| `version` | `\\\"latest\\\"` | MCP | Which tokens snapshot to fetch: `\\\"latest\\\"` or a published semver such as `\\\"1.4.0\\\"`. Set with `--tokens-version`. |\\n| `variablesOutput` | `\\\"src/bezel/variables.css\\\"` | build | Generated CSS file. Import this from the app entry. |\\n| `contextsOutput` | none | build | When set, writes a TypeScript module exporting `CONTEXTS` (the context names). |\\n| `fontsOutput` | none | build | When set, writes a TypeScript module exporting `FONTS` (web fonts derived from the tokens). |\\n| `contexts` | `{ \\\"$root\\\": \\\":root\\\", \\\"dark\\\": \\\".dark\\\", \\\"light\\\": \\\".light\\\" }` | build | Context name -> CSS selector. The first entry is the base context and is emitted in full; the rest are override-only blocks. |\\n| `colorFormat` | `\\\"oklch\\\"` | build | `\\\"oklch\\\"` or `\\\"hex\\\"`. |\\n| `dimensionUnit` | `\\\"preserve\\\"` | build | `\\\"preserve\\\"` keeps authored units; `\\\"rem\\\"` converts `px` to `rem`. |\\n| `nameExtension` | `\\\"com.bezel.app\\\"` | build | The `$extensions` key that holds `exportName`. Only change for files exported before the 0.3.0 rename. |\\n| `includeAll` | `false` | build | Also emit a variable for every token without an `exportName`, named by its kebab-cased path (`--base-color-primary-500`). |\\n| `write` | `true` | build | `false` returns the CSS without writing files (programmatic use). |\\n| `gitignore` | `true` | build | Maintain a `# bezel:start` ... `# bezel:end` block in `.gitignore` listing the generated outputs. |\\n| `gitignorePath` | `\\\".gitignore\\\"` | build | Which `.gitignore` to manage. |\\n| `cwd` | process cwd | build | Base directory paths resolve against. |\\n\\n`projectId` and `version` are ignored by `bezel build`; everything else is ignored by the MCP. The synced revision lives in `design-tokens-lock.json`, not here.\\n\\n## design-tokens-lock.json\\n\\nCommitted next to `design-tokens.json`, like `package-lock.json` next to `package.json`. It records the tokens and project revision this repo last synced or pushed: `lockfileVersion`, `projectId`, `version`, `revision`, and `tokens`. `bezel diff` compares `design-tokens.json` against it to find local edits. Only `bezel sync` writes it, after every sync and every push; never edit it. `bezel init --project` deletes a lockfile that belongs to a different project.\\n\\n## CLI\\n\\n```\\nbezel init [--project <uuid>] [--tokens-version <v>] [--dir <path>] ... create or update bezel.json\\nbezel build [--stdout] [--no-gitignore] ... generate the outputs (default command)\\nbezel install-mcp [--client <name>] connect an AI coding tool to the Bezel MCP\\nbezel install-skills [--client <name>] [--no-agents-md] install this skill into the repo\\nbezel diff [--json] local edits vs design-tokens-lock.json (--json: JSON Patch operations for a push)\\nbezel sync [--discard-local-edits] apply .bezel/sync.json: write the lockfile and design-tokens.json, then build\\n```\\n\\n`bezel sync` exits with code 2 when `design-tokens.json` has edits Bezel does not have; other problems exit with 1.\\n\\n`bezel init` on an existing `bezel.json` with `--project` or `--tokens-version` updates only those keys. Any other re-run leaves the file alone unless `--force` is passed, which agents must not do.\\n\",\n \"references/mcp-tools.md\": \"# Bezel MCP quick reference\\n\\nRemote server at `https://mcp.bezel.new/mcp` (Streamable HTTP, OAuth). The server returns data and instructions; the coding agent performs every local file edit and command. Project-scoped tools take the `projectId` from `bezel.json` or from `find-project`.\\n\\n## Guided workflows\\n\\n| Tool / prompt | Use |\\n|---|---|\\n| `setup-project` (tool and prompt) | Resumable setup: install bezel-kit, link a project, write `bezel.json`, fetch tokens, build, wire the CSS import, optional Crystal live preview. |\\n| `sync-project` (prompt) | Refresh `design-tokens.json` and `design-tokens-lock.json` from the linked project and version through `bezel sync`. Offers to push local edits first instead of overwriting them. |\\n| `push-project` (prompt) | Diff, preview, confirm with the user, and push the repo's token edits to the linked project, then sync so `design-tokens-lock.json` moves to the new revision. |\\n| `safe-usage-guide` (prompt) | Context-budget rules: manifest first, targeted queries, cite token paths. |\\n| `manifest-first-workflow`, `context-resolution` (prompts) | Recommended reading order and how contexts resolve. |\\n| `get-agent-guide` (tool) | Returns this skill's text when the repo has no local copy. |\\n\\n## Discovery\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `find-project` | `query?` | All owned projects (name + id), or one project resolved from a name or UUID. |\\n| `get-project-manifest` | `projectId` | Groups, token counts, types, contexts. No values. Call this first. |\\n\\n## Repo sync\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `get-design-tokens-file` | `projectId`, `version?` | `lockfileContent`: the full `design-tokens-lock.json` text (tokens + `revision`). Write it to `.bezel/sync.json` and run `npx bezel sync`. Unknown version -> list of available versions. |\\n| `preview-design-tokens-push` | `projectId`, `operations`, `baseRevision?`, `trackedVersion?` | Checks the edits from `npx bezel diff --json` against the working tokens: plan-limit problems, `conflict` (tokens edited here and in Bezel), themes the edits add (`addedContexts`), `behind` when Bezel moved on (those changes are kept), and a `confirmationPrompt` to show verbatim. Saves nothing. |\\n| `push-design-tokens` | `projectId`, `operations`, `baseRevision?` | Saves the previewed edits as a new revision. Call only after the user confirms the preview. Returns the new `revision`. Sync right after it so the lockfile moves to that revision. |\\n\\n## Reading tokens\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `query-tokens` | `projectId`, `groupPath?`, `tokenType?`, `search?`, `exportName?`, `contextKey?`, `resolveAliases?` | Filtered tokens. |\\n| `get-token-by-path` | `projectId`, `tokenPath`, `contextKey?`, `resolveAliases?` | One token with every context value and alias detail. |\\n| `get-token-bundle` | `projectId`, `intent` | Curated set: `theming-setup`, `button`, `card`, `input`, `form`, `auth-page`, `dashboard-shell`. |\\n| `get-project-contexts` | `projectId` | Context groups and values (theme modes, platforms, brands). |\\n| `resolve-context` | `projectId`, `contextGroup`, `contextValue` | Canonical context value or a structured error. |\\n\\n## Generating code\\n\\n| Tool | Parameters | Returns |\\n|---|---|---|\\n| `export-tokens` | `projectId`, `format` (`css-variables`, `js-object`, `ts-object`), filters, `prefix?`, `includeAll?` | Generated code with aliases resolved. |\\n| `get-framework-overrides` | `projectId`, `framework` (`tailwind`, `shadcn`, `mantine`), `version?`, filters | Framework config derived from the tokens. |\\n\\n## Color and unit math (deterministic)\\n\\n| Tool | Parameters |\\n|---|---|\\n| `contrast-check` | `foreground`, `background` -> WCAG ratio, grade, recommendations |\\n| `color-convert` | `color`, `targetFormat`, `manipulation?`, `mixColor?` |\\n| `color-ramp` | `baseColor`, `steps`, `endColor?`, `colorSpace?` |\\n| `unit-convert` | `value`, `fromUnit`, `toUnit`, `rootFontSize?`, `parentFontSize?` |\\n\\n## Review and history\\n\\n| Tool | Parameters |\\n|---|---|\\n| `design-review` | `projectId`, `componentDescription`, `tokenPathsUsed?`, `contextKey?` |\\n| `get-chat-history` | `projectId` |\\n| `search-chat-history` | `projectId`, `query` |\\n\\n## Resources\\n\\n- `bezel://projects`: your projects with ids and names.\\n- `bezel://agent-guide`: this skill's text.\\n\"\n },\n agentsMdBlock: \"## Bezel design tokens\\n\\n- `design-tokens.json` at the repo root is the source for every design token. Edit it to change a color, size, font, or radius, or to add a CSS variable (add an `exportName` under `$extensions[\\\"com.bezel.app\\\"]`).\\n- Files under the Bezel output folder (`variablesOutput`, `contextsOutput`, `fontsOutput` in `bezel.json`; `src/bezel/` by default) are generated. Never edit them; they are overwritten on every build.\\n- After changing `design-tokens.json` or `bezel.json`, run `npm run tokens` (or `npx bezel build`) and check the outputs were rewritten.\\n- Dark mode and other contexts are keys inside each token (`$root`, `dark`, `light`). Add a value under the context key instead of writing a CSS override.\\n- The Bezel app is the source of truth. `design-tokens-lock.json` records what was last synced or pushed; never edit it, and commit it together with `design-tokens.json`. `npx bezel diff` lists local edits that are not in Bezel yet.\\n- Sync through the Bezel MCP: write `get-design-tokens-file`'s `lockfileContent` to `.bezel/sync.json`, then run `npx bezel sync` (it writes both files and refuses to drop unpushed edits). To push, run `npx bezel diff --json`, call `preview-design-tokens-push` with its operations, show the confirmation prompt word for word, call `push-design-tokens` only after the user says yes, then sync to update the lockfile.\\n- Never run `bezel init --force`; it discards the existing `bezel.json`. Use `--project` or `--tokens-version` to update a single key.\\n- Full guidance: the `bezel` skill in `.claude/skills/bezel/SKILL.md` or `.agents/skills/bezel/SKILL.md`.\",\n summary: \"Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.\\n\\n## Hard rules\\n\\n1. Never edit a generated file. They start with `/* Generated by bezel — do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo's package manager runner). Confirm the outputs were rewritten before finishing.\\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `\\\"includeAll\\\": true`. Adding a token without an `exportName` produces no variable.\\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\\n6. Local edits to `design-tokens.json` are not in Bezel until they are pushed. `npx bezel diff` lists them. Never sync over them silently: offer to push them first. Pushing means `npx bezel diff --json`, `preview-design-tokens-push` with its operations, showing the `confirmationPrompt` word for word, `push-design-tokens` only after the user says yes, then a sync. Never push without that confirmation, and never push from a \\\"sync\\\" or \\\"pull\\\" request.\\n7. Never write or edit `design-tokens-lock.json`, and never write a synced `design-tokens.json` from MCP output yourself. Only `bezel sync` writes them, after every sync and every push, so the two files always agree. Commit both files together.\",\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,OAAO;AAAA,IACL,YAAY;AAAA,IACZ,4BAA4B;AAAA,IAC5B,2BAA2B;AAAA,EAC7B;AAAA,EACA,eAAe;AAAA,EACf,SAAS;AACX;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AGENT_SKILL
3
- } from "./chunk-S42THVKU.js";
3
+ } from "./chunk-NCIAL4MY.js";
4
4
  export {
5
5
  AGENT_SKILL
6
6
  };
@@ -371,6 +371,112 @@ export type FontDef = { family: string; weights: number[] }
371
371
  `;
372
372
  }
373
373
 
374
+ // src/lockfile.ts
375
+ var LOCKFILE_NAME = "design-tokens-lock.json";
376
+ var LOCKFILE_VERSION = 1;
377
+ var SYNC_STAGING_PATH = ".bezel/sync.json";
378
+ function buildLockfile(input) {
379
+ return {
380
+ lockfileVersion: LOCKFILE_VERSION,
381
+ projectId: input.projectId,
382
+ version: input.version,
383
+ revision: input.revision,
384
+ tokens: input.tokens
385
+ };
386
+ }
387
+ function serializeLockfile(lockfile) {
388
+ return `${JSON.stringify(lockfile, null, 2)}
389
+ `;
390
+ }
391
+ function serializeTokensFile(tokens) {
392
+ return `${JSON.stringify(tokens, null, 2)}
393
+ `;
394
+ }
395
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
396
+ function parseLockfile(text, name = LOCKFILE_NAME) {
397
+ let parsed;
398
+ try {
399
+ parsed = JSON.parse(text);
400
+ } catch {
401
+ const merged = /^(<<<<<<<|=======|>>>>>>>)/m.test(text);
402
+ return {
403
+ ok: false,
404
+ reason: "invalid-json",
405
+ message: merged ? `${name} has git merge conflict markers. Do not resolve them by hand; sync from Bezel to rewrite it.` : `${name} is not valid JSON. Sync from Bezel to rewrite it.`
406
+ };
407
+ }
408
+ if (!isRecord(parsed) || parsed["lockfileVersion"] !== LOCKFILE_VERSION || typeof parsed["projectId"] !== "string" || typeof parsed["version"] !== "string" || typeof parsed["revision"] !== "number" || !isRecord(parsed["tokens"])) {
409
+ return {
410
+ ok: false,
411
+ reason: "invalid-shape",
412
+ message: `${name} is not a version ${LOCKFILE_VERSION} Bezel lockfile. Sync from Bezel to rewrite it.`
413
+ };
414
+ }
415
+ return { ok: true, lockfile: parsed };
416
+ }
417
+
418
+ // src/patch-applied.ts
419
+ var MISSING = /* @__PURE__ */ Symbol("missing");
420
+ var decodeSegment = (segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~");
421
+ function valueAt(document, pointer) {
422
+ if (pointer === "") return document;
423
+ let node = document;
424
+ for (const raw of pointer.split("/").slice(1)) {
425
+ const segment = decodeSegment(raw);
426
+ if (Array.isArray(node)) {
427
+ const index = Number(segment);
428
+ if (!Number.isInteger(index) || index < 0 || index >= node.length) return MISSING;
429
+ node = node[index];
430
+ } else if (typeof node === "object" && node !== null && Object.prototype.hasOwnProperty.call(node, segment)) {
431
+ node = node[segment];
432
+ } else {
433
+ return MISSING;
434
+ }
435
+ }
436
+ return node;
437
+ }
438
+ function jsonEqual(a, b) {
439
+ if (a === b) return true;
440
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
441
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
442
+ if (Array.isArray(a) && Array.isArray(b)) {
443
+ return a.length === b.length && a.every((item, i) => jsonEqual(item, b[i]));
444
+ }
445
+ const aKeys = Object.keys(a);
446
+ const bKeys = Object.keys(b);
447
+ if (aKeys.length !== bKeys.length) return false;
448
+ return aKeys.every(
449
+ (key) => Object.prototype.hasOwnProperty.call(b, key) && jsonEqual(a[key], b[key])
450
+ );
451
+ }
452
+ function isOperationApplied(document, operation) {
453
+ switch (operation.op) {
454
+ case "test":
455
+ return true;
456
+ case "add":
457
+ case "replace": {
458
+ const current = valueAt(document, operation.path);
459
+ return current !== MISSING && jsonEqual(current, operation.value);
460
+ }
461
+ case "remove":
462
+ return valueAt(document, operation.path) === MISSING;
463
+ case "copy": {
464
+ const target = valueAt(document, operation.path);
465
+ return target !== MISSING && jsonEqual(target, valueAt(document, operation.from ?? ""));
466
+ }
467
+ case "move":
468
+ return valueAt(document, operation.path) !== MISSING && (operation.from === void 0 || valueAt(document, operation.from) === MISSING);
469
+ default:
470
+ return false;
471
+ }
472
+ }
473
+ function unappliedOperations(document, operations) {
474
+ return operations.filter((operation) => operation.op !== "test" && !isOperationApplied(document, operation));
475
+ }
476
+ function isPatchApplied(document, operations) {
477
+ return unappliedOperations(document, operations).length === 0;
478
+ }
479
+
374
480
  // src/index.ts
375
481
  function tokensToCss(tokens, options = {}) {
376
482
  return emitCss(tokens, resolveCssOptions(options));
@@ -394,6 +500,17 @@ export {
394
500
  formatContextsModule,
395
501
  getFonts,
396
502
  formatFontsModule,
503
+ LOCKFILE_NAME,
504
+ LOCKFILE_VERSION,
505
+ SYNC_STAGING_PATH,
506
+ buildLockfile,
507
+ serializeLockfile,
508
+ serializeTokensFile,
509
+ parseLockfile,
510
+ jsonEqual,
511
+ isOperationApplied,
512
+ unappliedOperations,
513
+ isPatchApplied,
397
514
  tokensToCss
398
515
  };
399
- //# sourceMappingURL=chunk-DXZXDPQ6.js.map
516
+ //# sourceMappingURL=chunk-N57FDE2K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/collapse.ts","../src/name.ts","../src/resolve.ts","../src/serialize.ts","../src/emit.ts","../src/defaults.ts","../src/options.ts","../src/contexts.ts","../src/fonts.ts","../src/lockfile.ts","../src/patch-applied.ts","../src/index.ts"],"sourcesContent":["import type { DtcgNode, FlatToken, TokenValue } from \"./types\"\n\n/** The W3C \"root token\" key — the base value of a group / logical token. */\nexport const ROOT_CONTEXT = \"$root\"\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v)\n}\n\n/** A \"context wrapper\" is a child object that directly holds a `$value` (e.g. `dark`, `light`, `$root`). */\nfunction isContextWrapper(v: unknown): v is DtcgNode {\n return isObject(v) && \"$value\" in v\n}\n\n/** Keys that are DTCG metadata, never traversed as child tokens/contexts. */\nfunction isMetaKey(key: string): boolean {\n return key === \"$type\" || key === \"$description\" || key === \"$extensions\" || key === \"$value\"\n}\n\n/**\n * Collapse a DTCG token tree to the single value that applies for `context`, and\n * flatten it to a map of dot-path → {@link FlatToken}.\n *\n * Handles three node shapes:\n * - **Simple token** — a node with a direct `$value` (context-invariant).\n * - **Logical token** — a node whose children include context wrappers (one of\n * which is `$root`). The value for `context` is picked, falling back to `$root`.\n * - **Group** — anything else; recursed into.\n *\n * `$type` is inherited from the nearest ancestor that declares one.\n */\nexport function flattenForContext(tokens: DtcgNode, context: string): Map<string, FlatToken> {\n const out = new Map<string, FlatToken>()\n\n const walk = (node: DtcgNode, path: string, inheritedType: string | undefined): void => {\n const type = typeof node.$type === \"string\" ? node.$type : inheritedType\n\n // Simple token: direct $value.\n if (\"$value\" in node) {\n out.set(path, {\n path,\n value: node.$value as TokenValue,\n type,\n extensions: node.$extensions,\n })\n return\n }\n\n // Logical token: has context-wrapper children (dark/light/$root).\n const wrapperKeys = Object.keys(node).filter((k) => !isMetaKey(k) && isContextWrapper(node[k]))\n if (wrapperKeys.length > 0) {\n const chosen =\n (node[context] as DtcgNode | undefined) ??\n (node[ROOT_CONTEXT] as DtcgNode | undefined) ??\n (node[wrapperKeys[0]!] as DtcgNode)\n out.set(path, {\n path,\n value: chosen.$value as TokenValue,\n type,\n extensions: node.$extensions,\n })\n return\n }\n\n // Group: recurse into non-meta children.\n for (const key of Object.keys(node)) {\n if (isMetaKey(key)) continue\n const child = node[key]\n if (isObject(child)) {\n walk(child as DtcgNode, path ? `${path}.${key}` : key, type)\n }\n }\n }\n\n walk(tokens, \"\", undefined)\n return out\n}\n","import type { FlatToken } from \"./types\"\n\n/** Leading path segments dropped when deriving a CSS name from a token path. */\nconst DROPPED_PREFIXES = new Set([\"base\", \"semantic\"])\n/** Trailing path segments dropped (a group's \"default\"/root token maps to the bare group name). */\nconst DROPPED_SUFFIXES = new Set([\"default\", \"$root\"])\n\nfunction exportNames(token: FlatToken, nameExtension: string): string[] | undefined {\n const ext = token.extensions?.[nameExtension]\n if (ext && typeof ext === \"object\" && \"exportName\" in ext) {\n const names = (ext as { exportName: unknown }).exportName\n if (Array.isArray(names)) return names.filter((n): n is string => typeof n === \"string\")\n }\n return undefined\n}\n\n/** True if any token in the map declares an `exportName` under `nameExtension`. */\nexport function usesExportNames(\n tokens: Iterable<FlatToken>,\n nameExtension: string,\n): boolean {\n for (const token of tokens) {\n if (exportNames(token, nameExtension) !== undefined) return true\n }\n return false\n}\n\n/** Derive a CSS variable name from a dot-path (fallback when no `exportName` exists). */\nexport function nameFromPath(path: string): string {\n const segments = path.split(\".\")\n while (segments.length > 1 && DROPPED_PREFIXES.has(segments[0]!)) segments.shift()\n while (segments.length > 1 && DROPPED_SUFFIXES.has(segments[segments.length - 1]!)) {\n segments.pop()\n }\n return segments.join(\"-\")\n}\n\n/**\n * Derive a CSS variable name from the full dot-path, kebab-cased (e.g.\n * `base.color.primary.500` → `base-color-primary-500`). Unlike {@link nameFromPath} it keeps\n * every segment, so the name identifies one token unambiguously.\n */\nexport function pathToKebabName(path: string): string {\n return path\n .split(\".\")\n .map((segment) =>\n segment\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\"),\n )\n .filter((segment) => segment.length > 0)\n .join(\"-\")\n}\n\n/**\n * Resolve the CSS variable name(s) a token emits (without the leading `--`).\n *\n * - In **exportName mode** (`useExportName`), names come solely from the token's\n * `exportName` array. A token without one — or with only empty strings — emits\n * nothing (it exists purely as a reference target). One token may emit many names.\n * - Otherwise (generic DTCG), the name is derived from the token's path.\n */\nexport function cssNames(\n token: FlatToken,\n nameExtension: string,\n useExportName: boolean,\n): string[] {\n if (useExportName) {\n const names = exportNames(token, nameExtension)\n if (!names) return []\n return names.filter((n) => n.length > 0)\n }\n return [nameFromPath(token.path)]\n}\n","import type { FlatToken, TokenValue } from \"./types\"\n\nconst REFERENCE_RE = /^\\{([^{}]+)\\}$/\n\n/** Returns the referenced path if `value` is a whole-value DTCG alias `\"{a.b.c}\"`, else `null`. */\nexport function aliasTarget(value: TokenValue): string | null {\n if (typeof value !== \"string\") return null\n const match = REFERENCE_RE.exec(value.trim())\n return match ? match[1]!.trim() : null\n}\n\n/**\n * Resolve whole-value references (`\"{a.b.c}\"`) in a flattened, single-context token\n * map, in place. Because the map was collapsed for one context, following an alias\n * yields that context's value (with `$root` fallback already applied during collapse).\n *\n * Multi-hop aliases are followed, results memoized, and cycles guarded against.\n */\nexport function resolveReferences(tokens: Map<string, FlatToken>): Map<string, FlatToken> {\n const resolved = new Map<string, TokenValue>()\n\n const resolveValue = (value: TokenValue, seen: Set<string>): TokenValue => {\n const target = aliasTarget(value)\n if (target === null) return value\n\n if (resolved.has(target)) return resolved.get(target)!\n if (seen.has(target)) {\n throw new Error(`bezel: circular token reference detected at \"{${target}}\".`)\n }\n\n const token = tokens.get(target)\n if (!token) {\n throw new Error(`bezel: unresolved token reference \"{${target}}\".`)\n }\n\n seen.add(target)\n const value2 = resolveValue(token.value, seen)\n seen.delete(target)\n resolved.set(target, value2)\n return value2\n }\n\n for (const token of tokens.values()) {\n token.value = resolveValue(token.value, new Set())\n }\n return tokens\n}\n","import type { ResolvedCssOptions } from \"./options\"\nimport type {\n ColorValue,\n DimensionValue,\n TokenValue,\n} from \"./types\"\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v)\n}\n\nfunction isColor(v: unknown): v is ColorValue {\n return isObject(v) && \"colorSpace\" in v && Array.isArray(v[\"components\"])\n}\n\nfunction isDimension(v: unknown): v is DimensionValue {\n return isObject(v) && typeof v[\"value\"] === \"number\" && \"unit\" in v\n}\n\n/** Round to at most `dp` decimals without trailing zeros. */\nfunction round(n: number, dp: number): number {\n const f = 10 ** dp\n return Math.round(n * f) / f\n}\n\nfunction serializeColor(color: ColorValue, format: ResolvedCssOptions[\"colorFormat\"]): string {\n if (format === \"hex\" && color.hex) return color.hex.toLowerCase()\n\n if (color.colorSpace === \"oklch\") {\n const [l = 0, c = 0, h = 0] = color.components\n const base = `oklch(${round(l, 4)} ${round(c, 4)} ${round(h, 3)})`\n if (color.alpha !== undefined && color.alpha < 1) {\n return `oklch(${round(l, 4)} ${round(c, 4)} ${round(h, 3)} / ${round(color.alpha, 4)})`\n }\n return base\n }\n\n // Unknown color space: prefer hex fallback, else CSS color() function.\n if (color.hex) return color.hex.toLowerCase()\n return `color(${color.colorSpace} ${color.components.map((n) => round(n, 4)).join(\" \")})`\n}\n\nfunction serializeDimension(dim: DimensionValue, unit: ResolvedCssOptions[\"dimensionUnit\"]): string {\n if (unit === \"rem\" && dim.unit === \"px\") {\n return `${round(dim.value / 16, 4)}rem`\n }\n return `${dim.value}${dim.unit}`\n}\n\n/** Quote a font-family name if it contains whitespace and isn't already quoted. */\nfunction quoteFamily(name: string): string {\n const trimmed = name.trim()\n if (/^['\"].*['\"]$/.test(trimmed)) return trimmed\n return /\\s/.test(trimmed) ? `\"${trimmed}\"` : trimmed\n}\n\n/** Serialize a resolved token value to a CSS declaration value. */\nexport function serializeValue(value: TokenValue, options: ResolvedCssOptions): string {\n if (isColor(value)) return serializeColor(value, options.colorFormat)\n if (isDimension(value)) return serializeDimension(value, options.dimensionUnit)\n\n // fontFamily as an array of names.\n if (Array.isArray(value)) {\n return value.map((v) => quoteFamily(String(v))).join(\", \")\n }\n\n if (typeof value === \"number\") return String(value)\n\n // Strings: could be a single font-family name or an already-formatted value.\n // Quote multi-word family names; leave comma-lists and plain values untouched.\n const str = String(value)\n if (/\\s/.test(str) && !str.includes(\",\") && !/[()]/.test(str)) {\n return quoteFamily(str)\n }\n return str\n}\n","import { flattenForContext } from \"./collapse\"\nimport { cssNames, pathToKebabName, usesExportNames } from \"./name\"\nimport { resolveReferences } from \"./resolve\"\nimport { serializeValue } from \"./serialize\"\nimport type { ResolvedCssOptions } from \"./options\"\nimport type { DtcgNode } from \"./types\"\n\n/** An ordered map of CSS variable name → serialized value for one context. */\ntype VarMap = Map<string, string>\n\n/** Build the `name → cssValue` map for a single context. */\nfunction buildContextVars(\n tokens: DtcgNode,\n context: string,\n useExportName: boolean,\n options: ResolvedCssOptions,\n): VarMap {\n const flat = resolveReferences(flattenForContext(tokens, context))\n const includeUnnamed = useExportName && options.includeAll\n\n // Export names always win over a generated path name, so collect them up front.\n const exportNames = new Set<string>()\n if (includeUnnamed) {\n for (const token of flat.values()) {\n for (const name of cssNames(token, options.nameExtension, true)) exportNames.add(name)\n }\n }\n\n const vars: VarMap = new Map()\n for (const token of flat.values()) {\n let names = cssNames(token, options.nameExtension, useExportName)\n if (names.length === 0 && includeUnnamed) {\n const generated = pathToKebabName(token.path)\n // First token wins among generated names; never shadow an export name.\n if (generated && !exportNames.has(generated) && !vars.has(generated)) names = [generated]\n }\n if (names.length === 0) continue\n const value = serializeValue(token.value, options)\n for (const name of names) vars.set(name, value)\n }\n return vars\n}\n\nfunction renderBlock(selector: string, vars: Iterable<[string, string]>): string {\n const lines = [...vars].map(([name, value]) => ` --${name}: ${value};`)\n if (lines.length === 0) return \"\"\n return `${selector} {\\n${lines.join(\"\\n\")}\\n}`\n}\n\n/**\n * Convert a DTCG token tree into a scoped CSS string. The first context in\n * `options.contexts` is the base (emitted in full); every other context emits\n * only the variables whose value differs from the base.\n */\nexport function emitCss(tokens: DtcgNode, options: ResolvedCssOptions): string {\n const contextNames = Object.keys(options.contexts)\n const useExportName = usesExportNames(\n flattenForContext(tokens, contextNames[0]!).values(),\n options.nameExtension,\n )\n\n const [baseContext, ...overrideContexts] = contextNames\n const baseVars = buildContextVars(tokens, baseContext!, useExportName, options)\n\n const blocks: string[] = [renderBlock(options.contexts[baseContext!]!, baseVars)]\n\n for (const context of overrideContexts) {\n const vars = buildContextVars(tokens, context, useExportName, options)\n const overrides = [...vars].filter(([name, value]) => baseVars.get(name) !== value)\n const block = renderBlock(options.contexts[context]!, overrides)\n if (block) blocks.push(block)\n }\n\n const header =\n \"/* Generated by bezel — do not edit by hand. */\\n\" +\n \"/* Run `npm run tokens` (or `bezel build`) to regenerate. */\\n\"\n return `${header}\\n${blocks.filter(Boolean).join(\"\\n\\n\")}\\n`\n}\n","/**\n * Pure default constants shared by the isomorphic core and the Node layer.\n * Kept free of `node:*` imports so the browser/edge entry can use them.\n */\n\n/** Default context → selector mapping. The first key is the base context. */\nexport const DEFAULT_CONTEXTS: Record<string, string> = {\n $root: \":root\",\n dark: \".dark\",\n light: \".light\",\n};\n\n/**\n * The DTCG input file the CLI reads from the project root. This is a cross-system\n * contract: it MUST stay in sync with the platform's `TOKENS_FILE_NAME` constant\n * so any repo/app the platform connects to resolves its tokens at the same name\n * and location.\n */\nexport const DEFAULT_INPUT = \"design-tokens.json\";\n\n/**\n * Directory generated outputs are written to, relative to the project root.\n *\n * Everything Bezel emits is generated and gitignored, and `bezel build` overwrites\n * without asking — so outputs live in their own directory rather than alongside\n * hand-written files, where a generic name like `variables.css` or `fonts.ts` could\n * silently clobber something the user wrote. {@link FALLBACK_OUTPUT_DIR} is used by\n * `bezel init` for projects with no `src/`.\n */\nexport const DEFAULT_OUTPUT_DIR = \"src/bezel\";\n/** Output directory `bezel init` picks when the project has no `src/`. */\nexport const FALLBACK_OUTPUT_DIR = \"bezel\";\n\n/** Generated output filenames, joined onto the output directory. */\nexport const VARIABLES_FILE = \"variables.css\";\nexport const CONTEXTS_FILE = \"contexts.ts\";\nexport const FONTS_FILE = \"fonts.ts\";\n\nexport const DEFAULT_VARIABLES_OUTPUT = `${DEFAULT_OUTPUT_DIR}/${VARIABLES_FILE}`;\nexport const DEFAULT_NAME_EXTENSION = \"com.bezel.app\";\n\n/** The config file `bezel init` writes and `bezel build` auto-loads from the project root. */\nexport const DEFAULT_CONFIG_FILE = \"bezel.json\";\n","import { DEFAULT_CONTEXTS, DEFAULT_NAME_EXTENSION } from \"./defaults\"\n\n/**\n * Options for the pure CSS transform ({@link tokensToCss}/{@link emitCss}),\n * decoupled from any filesystem concern so they work in any environment.\n * All optional; defaults make the zero-config case work.\n */\nexport interface CssOptions {\n /**\n * Map of context name → CSS selector. The first entry is the base context (full\n * output); every other context emits only the variables that differ from the base.\n * Default: `{ \"$root\": \":root\", \"dark\": \".dark\", \"light\": \".light\" }`.\n */\n contexts?: Record<string, string>\n /** Color serialization. Default: `\"oklch\"`. */\n colorFormat?: \"oklch\" | \"hex\"\n /** Dimension handling: keep the authored unit, or convert `px` → `rem`. Default: `\"preserve\"`. */\n dimensionUnit?: \"preserve\" | \"rem\"\n /** `$extensions` key holding the `exportName` array. Default: `\"com.bezel.app\"`. */\n nameExtension?: string\n /**\n * Also emit a variable for every token that has no `exportName`, named by kebab-casing its\n * full path (e.g. `base.color.primary.500` → `--base-color-primary-500`). Tokens with an\n * `exportName` still emit only their export names. Has no effect when no token declares an\n * `exportName`, since every token is then emitted with a path-derived name already.\n * Default: `false`.\n */\n includeAll?: boolean\n}\n\n/** Fully-resolved CSS-transform options (no `undefined`). */\nexport interface ResolvedCssOptions {\n contexts: Record<string, string>\n colorFormat: \"oklch\" | \"hex\"\n dimensionUnit: \"preserve\" | \"rem\"\n nameExtension: string\n includeAll: boolean\n}\n\n/** Apply defaults to {@link CssOptions}. Pure — no path resolution, no `node:*`. */\nexport function resolveCssOptions(options: CssOptions = {}): ResolvedCssOptions {\n const contexts = options.contexts ?? DEFAULT_CONTEXTS\n if (Object.keys(contexts).length === 0) {\n throw new Error(\"bezel: `contexts` must define at least one context.\")\n }\n\n return {\n contexts,\n colorFormat: options.colorFormat ?? \"oklch\",\n dimensionUnit: options.dimensionUnit ?? \"preserve\",\n nameExtension: options.nameExtension ?? DEFAULT_NAME_EXTENSION,\n includeAll: options.includeAll ?? false,\n }\n}\n","import { ROOT_CONTEXT } from \"./collapse\"\nimport type { DtcgNode } from \"./types\"\n\n/** Name the `$root` context maps to in generated output (matches the `:root` CSS scope). */\nexport const DEFAULT_CONTEXT_NAME = \"default\"\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v)\n}\n\nfunction isContextWrapper(v: unknown): boolean {\n return isObject(v) && \"$value\" in v\n}\n\n/**\n * Extract the distinct context names declared anywhere in a DTCG token tree.\n *\n * Walks to each logical token (a node with a `$root` context wrapper) and collects the\n * context keys it declares (`$root`, `dark`, `light`, …). `$root` is mapped to\n * `\"default\"` and placed first; the rest follow in first-seen order, deduped.\n */\nexport function getContexts(tokens: DtcgNode, rootName: string = DEFAULT_CONTEXT_NAME): string[] {\n const order: string[] = []\n const seen = new Set<string>()\n\n const walk = (node: DtcgNode): void => {\n if (ROOT_CONTEXT in node && isContextWrapper(node[ROOT_CONTEXT])) {\n for (const key of Object.keys(node)) {\n if (key.startsWith(\"$\") && key !== ROOT_CONTEXT) continue\n if (isContextWrapper(node[key]) && !seen.has(key)) {\n seen.add(key)\n order.push(key)\n }\n }\n return\n }\n for (const key of Object.keys(node)) {\n if (key.startsWith(\"$\")) continue\n const child = node[key]\n if (isObject(child)) walk(child as DtcgNode)\n }\n }\n\n walk(tokens)\n\n const mapped = order.map((k) => (k === ROOT_CONTEXT ? rootName : k))\n return [...new Set([rootName, ...mapped])]\n}\n\n/** Render the generated `contexts.ts` module emitted alongside `variables.css`. */\nexport function formatContextsModule(contexts: string[]): string {\n const list = contexts.map((c) => JSON.stringify(c)).join(\", \")\n return (\n \"/* Generated by bezel — do not edit by hand. */\\n\" +\n \"/* Run `npm run tokens` (or `bezel build`) to regenerate. */\\n\\n\" +\n `export const CONTEXTS = [${list}] as const\\n\\n` +\n \"export type Context = (typeof CONTEXTS)[number]\\n\"\n )\n}\n","import { flattenForContext, ROOT_CONTEXT } from \"./collapse\"\nimport { resolveReferences } from \"./resolve\"\nimport type { DtcgNode, TokenValue } from \"./types\"\n\n/** A web font to load: a family name and the weights it is used at. */\nexport interface FontDef {\n family: string\n weights: number[]\n}\n\n/** Generic CSS family keywords that are never loaded as web fonts. */\nconst GENERIC_FAMILIES = new Set([\n \"serif\",\n \"sans-serif\",\n \"monospace\",\n \"cursive\",\n \"fantasy\",\n \"system-ui\",\n \"ui-serif\",\n \"ui-sans-serif\",\n \"ui-monospace\",\n \"ui-rounded\",\n \"math\",\n \"emoji\",\n \"fangsong\",\n \"inherit\",\n \"initial\",\n \"unset\",\n])\n\nconst DEFAULT_WEIGHT = 400\n\n/** Resolve a fontFamily token value to a primary family name (first non-generic), or null. */\nfunction primaryFamily(value: TokenValue): string | null {\n const candidates = Array.isArray(value) ? value : [value]\n for (const candidate of candidates) {\n if (typeof candidate !== \"string\") continue\n const name = candidate.trim().replace(/^['\"]|['\"]$/g, \"\")\n if (name && !GENERIC_FAMILIES.has(name.toLowerCase())) return name\n }\n return null\n}\n\nfunction parentPath(path: string): string {\n const i = path.lastIndexOf(\".\")\n return i === -1 ? \"\" : path.slice(0, i)\n}\n\n/**\n * Extract the web fonts referenced by a DTCG token tree.\n *\n * Collects every distinct `fontFamily` value (references resolved), then derives each\n * family's weights from the semantic typography composites — a group whose `font-family`\n * resolves to that family contributes its sibling `font-weight`. Families used without an\n * accompanying weight default to `[400]`. Result is sorted by family for determinism.\n */\nexport function getFonts(tokens: DtcgNode): FontDef[] {\n const flat = resolveReferences(flattenForContext(tokens, ROOT_CONTEXT))\n\n const families = new Set<string>()\n const familyByParent = new Map<string, string>()\n const weightByParent = new Map<string, number>()\n\n for (const token of flat.values()) {\n if (token.type === \"fontFamily\") {\n const family = primaryFamily(token.value)\n if (family) {\n families.add(family)\n familyByParent.set(parentPath(token.path), family)\n }\n } else if (token.type === \"fontWeight\" && typeof token.value === \"number\") {\n weightByParent.set(parentPath(token.path), token.value)\n }\n }\n\n const weightsByFamily = new Map<string, Set<number>>()\n for (const [parent, family] of familyByParent) {\n const weight = weightByParent.get(parent)\n if (weight === undefined) continue\n const set = weightsByFamily.get(family) ?? new Set<number>()\n set.add(weight)\n weightsByFamily.set(family, set)\n }\n\n return [...families].sort().map((family) => {\n const weights = weightsByFamily.get(family)\n return {\n family,\n weights: weights ? [...weights].sort((a, b) => a - b) : [DEFAULT_WEIGHT],\n }\n })\n}\n\n/** Render the generated `fonts.ts` module emitted alongside `variables.css`. */\nexport function formatFontsModule(fonts: FontDef[]): string {\n const entries = fonts\n .map((f) => ` { family: ${JSON.stringify(f.family)}, weights: [${f.weights.join(\", \")}] },`)\n .join(\"\\n\")\n return (\n \"/* Generated by bezel — do not edit by hand. */\\n\" +\n \"/* Run `npm run tokens` (or `bezel build`) to regenerate. */\\n\\n\" +\n `export const FONTS = [\\n${entries}\\n] as const\\n\\n` +\n \"export type FontDef = { family: string; weights: number[] }\\n\"\n )\n}\n","/**\n * `design-tokens-lock.json`: what this repo last resolved from Bezel.\n *\n * Like `package-lock.json` next to `package.json`: `bezel.json` says which project and\n * version to track, the lockfile records the exact tokens and project revision the repo\n * last synced or pushed. Pushes diff `design-tokens.json` against the lockfile's tokens,\n * so only the edits travel. Committed to git, written only by Bezel Kit and the Bezel MCP.\n *\n * Pure: no `node:*`, so the Bezel MCP builds the same lockfile the CLI reads.\n */\n\nexport const LOCKFILE_NAME = \"design-tokens-lock.json\"\nexport const LOCKFILE_VERSION = 1\n/** Where an agent writes the lockfile text the Bezel MCP returns, for `bezel sync` to apply. */\nexport const SYNC_STAGING_PATH = \".bezel/sync.json\"\n\nexport interface TokensLockfile {\n lockfileVersion: typeof LOCKFILE_VERSION\n /** The Bezel project the tokens came from */\n projectId: string\n /** \"latest\" (working tokens) or the published semver that was synced */\n version: string\n /** The project revision the tokens belong to */\n revision: number\n /** The tokens exactly as Bezel holds them at `revision` */\n tokens: Record<string, unknown>\n}\n\nexport function buildLockfile(input: {\n projectId: string\n version: string\n revision: number\n tokens: Record<string, unknown>\n}): TokensLockfile {\n return {\n lockfileVersion: LOCKFILE_VERSION,\n projectId: input.projectId,\n version: input.version,\n revision: input.revision,\n tokens: input.tokens,\n }\n}\n\n/** The lockfile's on-disk text: 2-space JSON with a trailing newline. */\nexport function serializeLockfile(lockfile: TokensLockfile): string {\n return `${JSON.stringify(lockfile, null, 2)}\\n`\n}\n\n/** The `design-tokens.json` text Bezel Kit writes: 2-space JSON with a trailing newline. */\nexport function serializeTokensFile(tokens: Record<string, unknown>): string {\n return `${JSON.stringify(tokens, null, 2)}\\n`\n}\n\nexport type LockfileProblem = \"invalid-json\" | \"invalid-shape\"\n\nexport type ParseLockfileResult =\n | { ok: true; lockfile: TokensLockfile }\n | { ok: false; reason: LockfileProblem; message: string }\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\n/** Parses lockfile text and checks its shape. */\nexport function parseLockfile(text: string, name = LOCKFILE_NAME): ParseLockfileResult {\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n const merged = /^(<<<<<<<|=======|>>>>>>>)/m.test(text)\n return {\n ok: false,\n reason: \"invalid-json\",\n message: merged\n ? `${name} has git merge conflict markers. Do not resolve them by hand; sync from Bezel to rewrite it.`\n : `${name} is not valid JSON. Sync from Bezel to rewrite it.`,\n }\n }\n\n if (\n !isRecord(parsed) ||\n parsed[\"lockfileVersion\"] !== LOCKFILE_VERSION ||\n typeof parsed[\"projectId\"] !== \"string\" ||\n typeof parsed[\"version\"] !== \"string\" ||\n typeof parsed[\"revision\"] !== \"number\" ||\n !isRecord(parsed[\"tokens\"])\n ) {\n return {\n ok: false,\n reason: \"invalid-shape\",\n message: `${name} is not a version ${LOCKFILE_VERSION} Bezel lockfile. Sync from Bezel to rewrite it.`,\n }\n }\n\n return { ok: true, lockfile: parsed as unknown as TokensLockfile }\n}\n","/**\n * Whether RFC 6902 operations are already reflected in a document, without applying them.\n *\n * Two places need this. `bezel sync` uses it to tell local edits Bezel already has (a push\n * that landed) from edits that would be lost. The Bezel MCP uses it to recognize a push\n * that was already saved, so a repeat is \"no changes\" instead of a false conflict. Pure:\n * no dependencies, safe in any runtime.\n */\n\n/** One RFC 6902 operation, as produced by `fast-json-patch`'s `compare`. */\nexport interface JsonPatchOperation {\n op: \"add\" | \"remove\" | \"replace\" | \"move\" | \"copy\" | \"test\"\n path: string\n value?: unknown\n from?: string\n}\n\n/** Anything shaped like an operation, so `fast-json-patch`'s wider `Operation` type fits too. */\nexport interface PatchOperationLike {\n op: string\n path: string\n value?: unknown\n from?: string\n}\n\nconst MISSING = Symbol(\"missing\")\n\nconst decodeSegment = (segment: string) => segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\")\n\n/** The value at a JSON pointer, or `MISSING`. */\nfunction valueAt(document: unknown, pointer: string): unknown {\n if (pointer === \"\") return document\n let node: unknown = document\n for (const raw of pointer.split(\"/\").slice(1)) {\n const segment = decodeSegment(raw)\n if (Array.isArray(node)) {\n const index = Number(segment)\n if (!Number.isInteger(index) || index < 0 || index >= node.length) return MISSING\n node = node[index]\n } else if (typeof node === \"object\" && node !== null && Object.prototype.hasOwnProperty.call(node, segment)) {\n node = (node as Record<string, unknown>)[segment]\n } else {\n return MISSING\n }\n }\n return node\n}\n\n/** Structural equality for JSON values; object key order does not matter. */\nexport function jsonEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false\n if (Array.isArray(a) !== Array.isArray(b)) return false\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => jsonEqual(item, b[i]))\n }\n const aKeys = Object.keys(a as object)\n const bKeys = Object.keys(b as object)\n if (aKeys.length !== bKeys.length) return false\n return aKeys.every(\n (key) =>\n Object.prototype.hasOwnProperty.call(b, key) &&\n jsonEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]),\n )\n}\n\n/** True when the document already holds the result of this one operation. `test` is always true. */\nexport function isOperationApplied(document: unknown, operation: PatchOperationLike): boolean {\n switch (operation.op) {\n case \"test\":\n return true\n case \"add\":\n case \"replace\": {\n const current = valueAt(document, operation.path)\n return current !== MISSING && jsonEqual(current, operation.value)\n }\n case \"remove\":\n return valueAt(document, operation.path) === MISSING\n case \"copy\": {\n const target = valueAt(document, operation.path)\n return target !== MISSING && jsonEqual(target, valueAt(document, operation.from ?? \"\"))\n }\n case \"move\":\n return (\n valueAt(document, operation.path) !== MISSING &&\n (operation.from === undefined || valueAt(document, operation.from) === MISSING)\n )\n default:\n return false\n }\n}\n\n/** The operations (ignoring `test` guards) the document does not reflect yet. */\nexport function unappliedOperations<T extends PatchOperationLike>(document: unknown, operations: readonly T[]): T[] {\n return operations.filter((operation) => operation.op !== \"test\" && !isOperationApplied(document, operation))\n}\n\n/** True when every non-`test` operation is already reflected in the document. */\nexport function isPatchApplied(document: unknown, operations: readonly PatchOperationLike[]): boolean {\n return unappliedOperations(document, operations).length === 0\n}\n","/**\n * bezel — isomorphic entry.\n *\n * The pure transform core: convert an in-memory W3C Design Tokens (DTCG) object\n * into a scoped `variables.css` string. Imports no `node:*`, so it runs anywhere\n * — browser, edge, Node. For the filesystem/CLI conveniences (reading a tokens\n * file, writing outputs), import from `bezel/node`.\n */\nimport { emitCss } from \"./emit\"\nimport { resolveCssOptions, type CssOptions } from \"./options\"\nimport type { DtcgNode } from \"./types\"\n\nexport type { CssOptions, ResolvedCssOptions } from \"./options\"\nexport type { DtcgNode, FlatToken, TokenValue, ColorValue, DimensionValue } from \"./types\"\nexport { DEFAULT_CONTEXTS, DEFAULT_NAME_EXTENSION } from \"./defaults\"\nexport { emitCss } from \"./emit\"\nexport { resolveCssOptions } from \"./options\"\nexport { getContexts, formatContextsModule, DEFAULT_CONTEXT_NAME } from \"./contexts\"\nexport { getFonts, formatFontsModule } from \"./fonts\"\nexport type { FontDef } from \"./fonts\"\nexport {\n LOCKFILE_NAME,\n LOCKFILE_VERSION,\n SYNC_STAGING_PATH,\n buildLockfile,\n parseLockfile,\n serializeLockfile,\n serializeTokensFile,\n} from \"./lockfile\"\nexport type { TokensLockfile, ParseLockfileResult, LockfileProblem } from \"./lockfile\"\nexport { isOperationApplied, isPatchApplied, jsonEqual, unappliedOperations } from \"./patch-applied\"\nexport type { JsonPatchOperation, PatchOperationLike } from \"./patch-applied\"\nexport { AGENT_SKILL } from \"./agent-skill\"\nexport type { AgentSkill } from \"./agent-skill\"\n\n/**\n * Convert a DTCG token object into a scoped `variables.css` string.\n *\n * Resolves each configured context (with `$root` fallback and reference\n * resolution) and emits one CSS scope per context — the base context in full,\n * others as override-only blocks. Pure: no filesystem access.\n *\n * @example\n * const css = tokensToCss(tokens)\n *\n * @example\n * const css = tokensToCss(tokens, { colorFormat: \"hex\", contexts: { $root: \":root\" } })\n */\nexport function tokensToCss(tokens: DtcgNode, options: CssOptions = {}): string {\n return emitCss(tokens, resolveCssOptions(options))\n}\n"],"mappings":"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","names":["isObject","exportNames","isObject","isContextWrapper"]}
@@ -0,0 +1,17 @@
1
+ // src/agent-skill.ts
2
+ var AGENT_SKILL = {
3
+ name: "bezel",
4
+ description: "Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.",
5
+ files: {
6
+ "SKILL.md": '---\nname: bezel\ndescription: Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.\n---\n\n# Bezel in this repository\n\nBezel is a design-token platform. Designers maintain the tokens in the Bezel app; this repo holds an exported copy and generates CSS from it with `@bezel-labs/bezel-kit`.\n\n```\nBezel app (cloud, source of truth)\n -> design-tokens.json DTCG file at the repo root, exported from Bezel\n design-tokens-lock.json what was last synced or pushed (tokens + revision); commit it\n -> bezel build reads bezel.json for options and output paths\n -> variables.css one CSS scope per context (:root, .dark, .light, ...)\n contexts.ts, fonts.ts optional generated TypeScript modules\n```\n\nThe Bezel app stays the source of truth. Local edits to `design-tokens.json` reach Bezel only when they are pushed through the Bezel MCP, after a preview and the user\'s explicit yes (see "Pushing changes back to Bezel"); until then the next sync replaces them.\n\n## Hard rules\n\n1. Never edit a generated file. They start with `/* Generated by bezel \u2014 do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo\'s package manager runner). Confirm the outputs were rewritten before finishing.\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `"includeAll": true`. Adding a token without an `exportName` produces no variable.\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\n6. Local edits to `design-tokens.json` are not in Bezel until they are pushed. `npx bezel diff` lists them. Never sync over them silently: offer to push them first. Pushing means `npx bezel diff --json`, `preview-design-tokens-push` with its operations, showing the `confirmationPrompt` word for word, `push-design-tokens` only after the user says yes, then a sync. Never push without that confirmation, and never push from a "sync" or "pull" request.\n7. Never write or edit `design-tokens-lock.json`, and never write a synced `design-tokens.json` from MCP output yourself. Only `bezel sync` writes them, after every sync and every push, so the two files always agree. Commit both files together.\n\n## The tokens file\n\n`design-tokens.json` follows the W3C Design Tokens (DTCG) format. Every token is an object with a `$type` and one `$value` per context:\n\n```json\n"semantic": {\n "color": {\n "primary": {\n "$type": "color",\n "$root": { "$value": "{base.color.green.500}" },\n "dark": { "$value": { "colorSpace": "oklch", "components": [0.85, 0.16, 152] } },\n "$extensions": { "com.bezel.app": { "exportName": ["primary", "ring"] } }\n }\n }\n}\n```\n\n- Context keys (`$root`, `dark`, `light`, or whatever `bezel.json` `contexts` lists) sit inside the token. `$root` is the base; other contexts only need the values that differ.\n- `$value` is either a literal (DTCG color, dimension, font family, ...) or a reference like `{base.color.green.500}`. References are resolved to literal values in the generated CSS.\n- `$extensions["com.bezel.app"].exportName` is the list of CSS variable names the token emits. One token can emit several (`foreground`, `card-foreground`). An empty list means no variable.\n- Groups (`base`, `semantic`, `color`, ...) are plain nesting with no `$type`.\n\n## What to do for common requests\n\n| Request | Edit | Then |\n|---|---|---|\n| Change a color, size, radius, or font value | The token\'s `$value` in the right context key (`$root` for every mode, `dark` for dark mode only) | Rebuild |\n| A value should differ in dark mode | Add or edit the `dark` key on that token | Rebuild |\n| New CSS variable | Add a token with `$type`, `$root.$value`, and an `exportName` (or reference an existing token) | Rebuild |\n| Rename a CSS variable | Change the `exportName` entry; update every consumer of the old `--name` | Rebuild |\n| New theme or brand context | Add the context to `bezel.json` `contexts` (name -> selector) and add that key to the tokens that differ | Rebuild |\n| Change where files are generated | Edit `variablesOutput` / `contextsOutput` / `fontsOutput` in `bezel.json`; update the CSS import | Rebuild, delete the old outputs |\n| "Pull the latest tokens" / "sync from Bezel" | See the next section | `bezel sync` rebuilds |\n| "Push my changes to Bezel" / save local token edits back | Nothing by hand; follow "Pushing changes back to Bezel" | Sync, which updates the lockfile |\n\nFind the token for an existing variable by searching `design-tokens.json` for its name inside an `exportName` array.\n\n## Pulling the latest tokens from Bezel\n\n`bezel.json` `projectId` and `version` (`"latest"` or a published semver) say which Bezel project and snapshot this repo tracks. `design-tokens-lock.json` records the tokens and project revision this repo last synced or pushed, like `package-lock.json` next to `package.json`. Only `bezel sync` writes it.\n\nWith the Bezel MCP connected:\n\n1. Run `npx bezel diff`. If it lists local edits, stop and offer to push them first (next section). A lockfile problem it reports is fixed by this sync.\n2. Call `get-design-tokens-file` with that `projectId` and `version`. Write the returned `lockfileContent` exactly as returned to `.bezel/sync.json`.\n3. Run `npx bezel sync`. It checks the staged file, writes `design-tokens-lock.json` and then `design-tokens.json`, deletes the staged file, and rebuilds.\n - Exit code 2 means `design-tokens.json` has edits Bezel does not have. Show the message and offer to push them. Use `npx bezel sync --discard-local-edits` only when the user says to drop them.\n - `unknown command "sync"` means the installed `@bezel-labs/bezel-kit` is too old. Update it first.\n\nThe `sync-project` prompt walks through this, including linking a project when `projectId` is missing. Never pick a project or version yourself; ask when it is ambiguous.\n\nWithout the MCP: ask the user to download `design-tokens.json` from the project in the Bezel app and replace the file at the repo root, then rebuild. Pushing later needs a lockfile, so sync through the MCP when it becomes available.\n\n## Pushing changes back to Bezel\n\nNeeds the Bezel MCP. A push sends only your edits, as JSON Patch operations, the same way the Bezel app saves. Bezel applies them to the project\'s working tokens (`latest`) and keeps changes others made in the meantime. Publishing a version still happens in the Bezel app.\n\n1. Run `npx bezel diff --json`. `"ok": false` prints what to do (every lockfile problem is fixed by a sync). `"operations": []` means nothing to push.\n2. If `bezel.json` `version` is a semver, tell the user the push updates the working project, not that pinned release.\n3. Call `preview-design-tokens-push` with `projectId`, the printed `operations` and `baseRevision` unchanged, and `version` as `trackedVersion`. It saves nothing.\n4. `invalid` or `blocked`: report and stop (`blocked` is a plan limit). `conflict`: the listed tokens changed in Bezel too; follow `nextStep`. `no-changes` with `alreadyApplied`: an earlier push saved these edits but the sync after it did not run; sync now. Themes the edits use that the project lacks are added by the push (`addedContexts`).\n5. `ready`: show `confirmationPrompt` to the user word for word and wait. Do not push on silence, a question, or a different request.\n6. After an explicit yes, call `push-design-tokens` with the same `projectId`, `operations`, and `baseRevision`.\n7. A push is not finished until the repo is synced. Sync as in the previous section, steps 2 and 3: `get-design-tokens-file`, write `lockfileContent` to `.bezel/sync.json`, run `npx bezel sync`. Your edits are already in Bezel, so the sync keeps them, pulls in anything others changed, and moves the lockfile to the new revision. Then tell the user to commit `design-tokens.json` and `design-tokens-lock.json` together.\n\nThe `push-project` prompt walks through this.\n\n## With the Bezel MCP connected\n\nPrefer small, targeted calls over reading the whole tokens file:\n\n- `get-project-manifest` first: groups, counts, types, contexts, no values.\n- `query-tokens` to find tokens by group, type, name, or `exportName`; `get-token-by-path` for one token with every context value.\n- `get-token-bundle` for a curated set per task (`theming-setup`, `button`, `card`, `form`, ...).\n- `export-tokens` and `get-framework-overrides` to generate CSS, JS/TS objects, or Tailwind / shadcn / Mantine config from tokens.\n- `contrast-check`, `color-convert`, `color-ramp`, `unit-convert` for deterministic math instead of estimating.\n- `design-review` to check a component description against the tokens.\n\nSee `references/mcp-tools.md` for the full list and `references/bezel-json.md` for every config field.\n\n## Setting up a repo that is not on Bezel yet\n\nRun the `setup-project` tool (or the `/mcp__bezel__setup-project` prompt) and follow it; it installs `@bezel-labs/bezel-kit`, writes `bezel.json`, fetches the tokens, builds, and wires the CSS import. Do not improvise the steps.\n',
7
+ "references/bezel-json.md": '# bezel.json reference\n\n`bezel.json` lives at the repo root (or the working directory `bezel build` runs in). `bezel build` loads it automatically; `bezel init` writes it. The tokens input is always `design-tokens.json` in that same directory and is not configurable.\n\n| Field | Default | Used by | Meaning |\n|---|---|---|---|\n| `projectId` | none | MCP | UUID of the Bezel project this repo tracks. Set with `npx bezel init --project <uuid>`. |\n| `version` | `"latest"` | MCP | Which tokens snapshot to fetch: `"latest"` or a published semver such as `"1.4.0"`. Set with `--tokens-version`. |\n| `variablesOutput` | `"src/bezel/variables.css"` | build | Generated CSS file. Import this from the app entry. |\n| `contextsOutput` | none | build | When set, writes a TypeScript module exporting `CONTEXTS` (the context names). |\n| `fontsOutput` | none | build | When set, writes a TypeScript module exporting `FONTS` (web fonts derived from the tokens). |\n| `contexts` | `{ "$root": ":root", "dark": ".dark", "light": ".light" }` | build | Context name -> CSS selector. The first entry is the base context and is emitted in full; the rest are override-only blocks. |\n| `colorFormat` | `"oklch"` | build | `"oklch"` or `"hex"`. |\n| `dimensionUnit` | `"preserve"` | build | `"preserve"` keeps authored units; `"rem"` converts `px` to `rem`. |\n| `nameExtension` | `"com.bezel.app"` | build | The `$extensions` key that holds `exportName`. Only change for files exported before the 0.3.0 rename. |\n| `includeAll` | `false` | build | Also emit a variable for every token without an `exportName`, named by its kebab-cased path (`--base-color-primary-500`). |\n| `write` | `true` | build | `false` returns the CSS without writing files (programmatic use). |\n| `gitignore` | `true` | build | Maintain a `# bezel:start` ... `# bezel:end` block in `.gitignore` listing the generated outputs. |\n| `gitignorePath` | `".gitignore"` | build | Which `.gitignore` to manage. |\n| `cwd` | process cwd | build | Base directory paths resolve against. |\n\n`projectId` and `version` are ignored by `bezel build`; everything else is ignored by the MCP. The synced revision lives in `design-tokens-lock.json`, not here.\n\n## design-tokens-lock.json\n\nCommitted next to `design-tokens.json`, like `package-lock.json` next to `package.json`. It records the tokens and project revision this repo last synced or pushed: `lockfileVersion`, `projectId`, `version`, `revision`, and `tokens`. `bezel diff` compares `design-tokens.json` against it to find local edits. Only `bezel sync` writes it, after every sync and every push; never edit it. `bezel init --project` deletes a lockfile that belongs to a different project.\n\n## CLI\n\n```\nbezel init [--project <uuid>] [--tokens-version <v>] [--dir <path>] ... create or update bezel.json\nbezel build [--stdout] [--no-gitignore] ... generate the outputs (default command)\nbezel install-mcp [--client <name>] connect an AI coding tool to the Bezel MCP\nbezel install-skills [--client <name>] [--no-agents-md] install this skill into the repo\nbezel diff [--json] local edits vs design-tokens-lock.json (--json: JSON Patch operations for a push)\nbezel sync [--discard-local-edits] apply .bezel/sync.json: write the lockfile and design-tokens.json, then build\n```\n\n`bezel sync` exits with code 2 when `design-tokens.json` has edits Bezel does not have; other problems exit with 1.\n\n`bezel init` on an existing `bezel.json` with `--project` or `--tokens-version` updates only those keys. Any other re-run leaves the file alone unless `--force` is passed, which agents must not do.\n',
8
+ "references/mcp-tools.md": "# Bezel MCP quick reference\n\nRemote server at `https://mcp.bezel.new/mcp` (Streamable HTTP, OAuth). The server returns data and instructions; the coding agent performs every local file edit and command. Project-scoped tools take the `projectId` from `bezel.json` or from `find-project`.\n\n## Guided workflows\n\n| Tool / prompt | Use |\n|---|---|\n| `setup-project` (tool and prompt) | Resumable setup: install bezel-kit, link a project, write `bezel.json`, fetch tokens, build, wire the CSS import, optional Crystal live preview. |\n| `sync-project` (prompt) | Refresh `design-tokens.json` and `design-tokens-lock.json` from the linked project and version through `bezel sync`. Offers to push local edits first instead of overwriting them. |\n| `push-project` (prompt) | Diff, preview, confirm with the user, and push the repo's token edits to the linked project, then sync so `design-tokens-lock.json` moves to the new revision. |\n| `safe-usage-guide` (prompt) | Context-budget rules: manifest first, targeted queries, cite token paths. |\n| `manifest-first-workflow`, `context-resolution` (prompts) | Recommended reading order and how contexts resolve. |\n| `get-agent-guide` (tool) | Returns this skill's text when the repo has no local copy. |\n\n## Discovery\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `find-project` | `query?` | All owned projects (name + id), or one project resolved from a name or UUID. |\n| `get-project-manifest` | `projectId` | Groups, token counts, types, contexts. No values. Call this first. |\n\n## Repo sync\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `get-design-tokens-file` | `projectId`, `version?` | `lockfileContent`: the full `design-tokens-lock.json` text (tokens + `revision`). Write it to `.bezel/sync.json` and run `npx bezel sync`. Unknown version -> list of available versions. |\n| `preview-design-tokens-push` | `projectId`, `operations`, `baseRevision?`, `trackedVersion?` | Checks the edits from `npx bezel diff --json` against the working tokens: plan-limit problems, `conflict` (tokens edited here and in Bezel), themes the edits add (`addedContexts`), `behind` when Bezel moved on (those changes are kept), and a `confirmationPrompt` to show verbatim. Saves nothing. |\n| `push-design-tokens` | `projectId`, `operations`, `baseRevision?` | Saves the previewed edits as a new revision. Call only after the user confirms the preview. Returns the new `revision`. Sync right after it so the lockfile moves to that revision. |\n\n## Reading tokens\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `query-tokens` | `projectId`, `groupPath?`, `tokenType?`, `search?`, `exportName?`, `contextKey?`, `resolveAliases?` | Filtered tokens. |\n| `get-token-by-path` | `projectId`, `tokenPath`, `contextKey?`, `resolveAliases?` | One token with every context value and alias detail. |\n| `get-token-bundle` | `projectId`, `intent` | Curated set: `theming-setup`, `button`, `card`, `input`, `form`, `auth-page`, `dashboard-shell`. |\n| `get-project-contexts` | `projectId` | Context groups and values (theme modes, platforms, brands). |\n| `resolve-context` | `projectId`, `contextGroup`, `contextValue` | Canonical context value or a structured error. |\n\n## Generating code\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `export-tokens` | `projectId`, `format` (`css-variables`, `js-object`, `ts-object`), filters, `prefix?`, `includeAll?` | Generated code with aliases resolved. |\n| `get-framework-overrides` | `projectId`, `framework` (`tailwind`, `shadcn`, `mantine`), `version?`, filters | Framework config derived from the tokens. |\n\n## Color and unit math (deterministic)\n\n| Tool | Parameters |\n|---|---|\n| `contrast-check` | `foreground`, `background` -> WCAG ratio, grade, recommendations |\n| `color-convert` | `color`, `targetFormat`, `manipulation?`, `mixColor?` |\n| `color-ramp` | `baseColor`, `steps`, `endColor?`, `colorSpace?` |\n| `unit-convert` | `value`, `fromUnit`, `toUnit`, `rootFontSize?`, `parentFontSize?` |\n\n## Review and history\n\n| Tool | Parameters |\n|---|---|\n| `design-review` | `projectId`, `componentDescription`, `tokenPathsUsed?`, `contextKey?` |\n| `get-chat-history` | `projectId` |\n| `search-chat-history` | `projectId`, `query` |\n\n## Resources\n\n- `bezel://projects`: your projects with ids and names.\n- `bezel://agent-guide`: this skill's text.\n"
9
+ },
10
+ agentsMdBlock: '## Bezel design tokens\n\n- `design-tokens.json` at the repo root is the source for every design token. Edit it to change a color, size, font, or radius, or to add a CSS variable (add an `exportName` under `$extensions["com.bezel.app"]`).\n- Files under the Bezel output folder (`variablesOutput`, `contextsOutput`, `fontsOutput` in `bezel.json`; `src/bezel/` by default) are generated. Never edit them; they are overwritten on every build.\n- After changing `design-tokens.json` or `bezel.json`, run `npm run tokens` (or `npx bezel build`) and check the outputs were rewritten.\n- Dark mode and other contexts are keys inside each token (`$root`, `dark`, `light`). Add a value under the context key instead of writing a CSS override.\n- The Bezel app is the source of truth. `design-tokens-lock.json` records what was last synced or pushed; never edit it, and commit it together with `design-tokens.json`. `npx bezel diff` lists local edits that are not in Bezel yet.\n- Sync through the Bezel MCP: write `get-design-tokens-file`\'s `lockfileContent` to `.bezel/sync.json`, then run `npx bezel sync` (it writes both files and refuses to drop unpushed edits). To push, run `npx bezel diff --json`, call `preview-design-tokens-push` with its operations, show the confirmation prompt word for word, call `push-design-tokens` only after the user says yes, then sync to update the lockfile.\n- Never run `bezel init --force`; it discards the existing `bezel.json`. Use `--project` or `--tokens-version` to update a single key.\n- Full guidance: the `bezel` skill in `.claude/skills/bezel/SKILL.md` or `.agents/skills/bezel/SKILL.md`.',
11
+ summary: 'Use when the repo has bezel.json or design-tokens.json and the task touches design tokens, theme colors, spacing, typography, radii, CSS variables, dark mode, or files under the Bezel output folder (src/bezel by default). Edit design-tokens.json, never the generated variables.css / contexts.ts / fonts.ts, then run the tokens build. Also covers pulling the latest tokens from the Bezel app, pushing local token edits back to Bezel after a preview and confirmation, and using the Bezel MCP tools.\n\n## Hard rules\n\n1. Never edit a generated file. They start with `/* Generated by bezel \u2014 do not edit by hand. */` and live at the paths named in `bezel.json` (`variablesOutput`, `contextsOutput`, `fontsOutput`; default folder `src/bezel/`). `bezel build` overwrites them without asking and they are gitignored.\n2. To change a token value or add a variable, edit `design-tokens.json`, then rebuild. Never hand-write the CSS variable.\n3. After any change to `design-tokens.json` or `bezel.json`, run the tokens build: `npm run tokens` when that script exists, otherwise `npx bezel build` (use the repo\'s package manager runner). Confirm the outputs were rewritten before finishing.\n4. Only tokens with an `exportName` become CSS variables unless `bezel.json` sets `"includeAll": true`. Adding a token without an `exportName` produces no variable.\n5. Never pass `--force` to `bezel init`; it discards the existing `bezel.json`. `--project` and `--tokens-version` update their own keys without it.\n6. Local edits to `design-tokens.json` are not in Bezel until they are pushed. `npx bezel diff` lists them. Never sync over them silently: offer to push them first. Pushing means `npx bezel diff --json`, `preview-design-tokens-push` with its operations, showing the `confirmationPrompt` word for word, `push-design-tokens` only after the user says yes, then a sync. Never push without that confirmation, and never push from a "sync" or "pull" request.\n7. Never write or edit `design-tokens-lock.json`, and never write a synced `design-tokens.json` from MCP output yourself. Only `bezel sync` writes them, after every sync and every push, so the two files always agree. Commit both files together.'
12
+ };
13
+
14
+ export {
15
+ AGENT_SKILL
16
+ };
17
+ //# sourceMappingURL=chunk-NCIAL4MY.js.map