@csszyx/mcp-server 0.10.0 → 0.10.2

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.
Files changed (2) hide show
  1. package/llms-full.txt +94 -13
  2. package/package.json +4 -4
package/llms-full.txt CHANGED
@@ -248,11 +248,15 @@ compile error, so typos and legacy CSS-property names are caught by `tsc` (run
248
248
  `tsc --noEmit` in CI to enforce it).
249
249
 
250
250
  ```tsx
251
- { bgColor: 'red-500' } // ❌ tsc error — unknown key; canonical is { bg: 'red-500' }
251
+ {
252
+ bgColor: "red-500";
253
+ } // ❌ tsc error — unknown key; canonical is { bg: 'red-500' }
252
254
 
253
255
  // Forcing a brand-new Tailwind utility csszyx has no key for yet — opt out explicitly:
254
256
  // @ts-expect-error - forward-compat utility not yet in csszyx
255
- { someNewUtility: 'x' } // ✅ allowed; the runtime still emits the class
257
+ {
258
+ someNewUtility: "x";
259
+ } // ✅ allowed; the runtime still emits the class
256
260
  ```
257
261
 
258
262
  Arbitrary variants are allowed by pattern: `{ '@container': {…} }`, `{ 'min-[320px]': {…} }`,
@@ -260,7 +264,9 @@ Arbitrary variants are allowed by pattern: `{ '@container': {…} }`, `{ 'min-[3
260
264
  Tailwind `@theme` and csszyx auto-generates the type:
261
265
 
262
266
  ```css
263
- @theme { --breakpoint-tablet: 40rem; } /* → { tablet: { p: 6 } } now type-checks */
267
+ @theme {
268
+ --breakpoint-tablet: 40rem;
269
+ } /* → { tablet: { p: 6 } } now type-checks */
264
270
  ```
265
271
 
266
272
  ## Full Snippets Reference
@@ -3511,37 +3517,112 @@ import { __szColorVar } from "csszyx/lite";
3511
3517
  When a caller passes one flat `className` to a component that renders nested elements, `splitBox` partitions it at the CSS box-model border line so each element gets the classes that act on it. Pure string functions, framework-agnostic. The class-token → box-role map is generated from the compiler's property tables (never drifts).
3512
3518
 
3513
3519
  ```tsx
3514
- import { splitBox, classify, has, pick, omit, stripSzProps } from '@csszyx/runtime';
3520
+ import {
3521
+ splitBox,
3522
+ splitBoxSz,
3523
+ classify,
3524
+ has,
3525
+ pick,
3526
+ omit,
3527
+ stripSzProps,
3528
+ } from "@csszyx/runtime";
3515
3529
 
3516
3530
  // Partition: outer = border-outward (margin/position/border/sizing/bg/shadow/transform/visibility),
3517
3531
  // inner = border-inward (padding/overflow/display/layout/gap/text/paint-inside/interactivity)
3518
- const { outer, inner } = splitBox('m-4 px-2 md:flex');
3532
+ const { outer, inner } = splitBox("m-4 px-2 md:flex");
3519
3533
  // outer: "m-4" inner: "px-2 md:flex"
3520
3534
 
3521
3535
  // Override any default per call (BoxSelector = box-role | category | class-prefix | { category: value })
3522
- splitBox('overflow-hidden p-4', { outer: ['overflow'] });
3536
+ splitBox("overflow-hidden p-4", { outer: ["overflow"] });
3523
3537
  // outer: "overflow-hidden" inner: "p-4"
3524
3538
 
3525
3539
  // Toolkit: csszyx owns the truth (box-role/category), your project owns the rule
3526
- classify('inset-ring-2'); // { role: 'inner', category: 'ring' }
3527
- has('p-2 overflow-y-auto', 'overflow'); // true
3528
- pick('m-4 text-sm', 'text'); // "text-sm"
3529
- omit('p-2 overflow-y-auto flex', 'overflow'); // "p-2 flex"
3540
+ classify("inset-ring-2"); // { role: 'inner', category: 'ring' }
3541
+ has("p-2 overflow-y-auto", "overflow"); // true
3542
+ pick("m-4 text-sm", "text"); // "text-sm"
3543
+ omit("p-2 overflow-y-auto flex", "overflow"); // "p-2 flex"
3530
3544
 
3531
3545
  // A scroller scrolls only when the outer frame clips (project-owned dependency rule)
3532
- const dep = has(outer, { overflow: 'hidden' }) ? 'overflow-y-auto h-full' : '';
3546
+ const dep = has(outer, { overflow: "hidden" }) ? "overflow-y-auto h-full" : "";
3547
+
3548
+ // sz-OBJECT routing: splitBoxSz partitions an sz OBJECT (not a className) into
3549
+ // { outer, inner } sz objects — keeps a szv-based component sz-native and routes
3550
+ // each key to the same side its class would (splitBoxSz(x) ≡ splitBox(compile(x))).
3551
+ splitBoxSz({ m: 4, px: 2 }); // { outer: { m: 4 }, inner: { px: 2 } }
3552
+ splitBoxSz({ gap: 2, hover: { px: 1 }, md: { m: 4 } }); // variants route by inner prop; split when they disagree
3553
+ splitBoxSz({ grow: 2, self: "center" }, { outer: ["grow", "self"] }); // force flex-item utils to the frame
3554
+ // classifySzKey(key) / hasSz / pickSz / omitSz — the sz-object toolkit twins
3533
3555
 
3534
3556
  // stripSzProps: drop sz before forwarding ...rest to the DOM (guards uncompiled files
3535
3557
  // whose raw sz would leak as sz="[object Object]"; dev-warns once on a raw-object sz)
3536
- function Box({ sz, ...rest }) { return <div {...stripSzProps(rest)} />; }
3558
+ function Box({ sz, ...rest }) {
3559
+ return <div {...stripSzProps(rest)} />;
3560
+ }
3537
3561
  ```
3538
3562
 
3563
+ ## Build-time vs runtime (when does sz become CSS)
3564
+
3565
+ csszyx has two worlds; pick by "is the value set finite and known at build time?".
3566
+
3567
+ - **Static (build-time, default):** literals + `szv` variants. The compiler lowers
3568
+ sz → Tailwind classes and safelists them; Tailwind generates CSS at build. Zero
3569
+ runtime, SSR-safe.
3570
+ - **Runtime (`dynamic()`):** unbounded values (CMS color, user `#hex`). CSS is
3571
+ generated + injected in the browser via insertRule. Escape hatch only.
3572
+
3573
+ Engines (BUILD-TIME parse of JSX source only): Rust native (default) → oxc (JS
3574
+ fallback) → babel (last resort). The RUNTIME has no parser: `_sz`/`szv`/`splitBox`
3575
+ are plain JS; `dynamic()` lowers an sz OBJECT via `@csszyx/compiler/browser` (pure
3576
+ JS, no JSX parsing).
3577
+
3578
+ Helper build-time/runtime:
3579
+
3580
+ - `sz={{…}}` literal → build-time (extracted + safelisted).
3581
+ - `szv` → build-time: the compiler extracts the `szv({…})` config from its
3582
+ DECLARATION, regardless of how the factory output is used (direct sz=, through
3583
+ splitBoxSz, or unused). Indirection does NOT break safelisting.
3584
+ - `splitBox`/`splitBoxSz` → RUNTIME routing only (pure JS). They re-partition
3585
+ existing classes; they emit no new CSS and do NOT force `dynamic()`. CSS comes
3586
+ from the static source (a literal or a szv config).
3587
+ - `dynamic()` → the only helper that generates CSS at runtime, and only for a
3588
+ class not already in the built CSS.
3589
+
3590
+ Safelist requires a statically analyzable position (a literal sz, or a szv config
3591
+ literal). File-discovery gap: the prescan only scans files containing `sz=`/`sz:`,
3592
+ so a standalone szv-config file (no JSX) is skipped → co-locate szv in the
3593
+ component file that has a `sz=` usage. For a sibling workspace package, opt it in
3594
+ with `compilePackages: ['name']`.
3595
+
3596
+ Tree-shaking is content-presence (same as Tailwind), not import-graph. Co-locating
3597
+ szv makes the component the shaking unit.
3598
+
3599
+ Specificity: a `dynamic()`-injected rule is UNLAYERED → beats static sz / Tailwind
3600
+ `@layer utilities` at equal specificity (CSS Cascade Level 5). They don't collide
3601
+ by design (dynamic injects only not-yet-built classes); prefer all-static in a
3602
+ component.
3603
+
3604
+ CRITICAL — sz on an HTML tag vs a component: the compiler rewrites `sz=` to
3605
+ `className=` on ANY element. On an html tag (`<div sz>`) the class lands on the DOM
3606
+ and applies. On a COMPONENT (`<Box sz={{p:4}}>` → `<Box className="p-4">`) the
3607
+ class becomes a `className` PROP — the component does NOT receive an sz object and
3608
+ MUST forward `className` onto a real html tag, else the style is lost. Putting sz
3609
+ on a component is NOT enough; every style must reach an html tag.
3610
+
3611
+ Design-system rules: (1) a component is styled from the app via the `className` it
3612
+ receives (the compiled app sz); forward it to a DOM tag
3613
+ (`function Box({className}) { return <div className={className}/> }`). NEVER
3614
+ `dynamic(sz)` inside a component (makes every consumer runtime). (2) a multi-part
3615
+ component receives ONE className and routes it with `splitBox(className)` (STRING),
3616
+ combining with its own base classes on plain className (don't mix sz= and
3617
+ className= on one element). `splitBoxSz` (object) is only for routing an sz object
3618
+ the component builds internally (e.g. from szv) onto nested sz= props.
3619
+
3539
3620
  ## Security — untrusted sz
3540
3621
 
3541
3622
  csszyx is safe-by-default for AUTHORED sz (compiled to class strings at build time). When sz comes from UNTRUSTED input (JSON-driven UI, CMS, user data), it controls keys and values that reach the runtime CSS pipeline — purify it.
3542
3623
 
3543
3624
  ```tsx
3544
- import { dynamic, purifySz } from '@csszyx/dynamic';
3625
+ import { dynamic, purifySz } from "@csszyx/dynamic";
3545
3626
  // stripSzProps is exported from '@csszyx/runtime'
3546
3627
 
3547
3628
  // Untrusted sz → dynamic() runtime CSS: purify first (allowlist + value sanitize + proto guard)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@csszyx/mcp-server",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Model Context Protocol (MCP) server for csszyx — enables AI agents to understand and generate sz props",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,9 +30,9 @@
30
30
  "dependencies": {
31
31
  "@modelcontextprotocol/sdk": "^1.29.0",
32
32
  "zod": "^3.23.8",
33
- "@csszyx/cli": "0.10.0",
34
- "@csszyx/unplugin": "0.10.0",
35
- "@csszyx/compiler": "0.10.0"
33
+ "@csszyx/cli": "0.10.2",
34
+ "@csszyx/compiler": "0.10.2",
35
+ "@csszyx/unplugin": "0.10.2"
36
36
  },
37
37
  "devDependencies": {
38
38
  "typescript": "^6.0.3",