fractalstyler2 0.1.0 → 0.3.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.
Files changed (58) hide show
  1. package/README.md +60 -58
  2. package/dist/cli.js +47 -9
  3. package/dist/index.d.ts +32 -1
  4. package/dist/index.js +73 -4
  5. package/dist/mcp/export.d.ts +13 -0
  6. package/dist/mcp/export.js +76 -0
  7. package/dist/mcp/schemas/compile_fractals.json +20 -0
  8. package/dist/mcp/schemas/css_to_fractals.json +16 -0
  9. package/dist/mcp/schemas/generate_component.json +45 -0
  10. package/dist/mcp/schemas/get_design_tokens.json +23 -0
  11. package/dist/mcp/schemas/instructions.md +18 -0
  12. package/dist/mcp/schemas/list_fractals.json +20 -0
  13. package/dist/mcp/schemas/snap_to_tokens.json +25 -0
  14. package/dist/mcp/schemas/validate_recipe.json +16 -0
  15. package/dist/mcp/server.js +28 -12
  16. package/dist/styles/_00_tokens.sass +177 -0
  17. package/{templates/_config.sass → dist/styles/_01_config.sass} +11 -5
  18. package/dist/styles/_02_fonts.sass +13 -0
  19. package/dist/styles/_03_responsive.sass +31 -0
  20. package/dist/styles/{_atoms.sass → _04_atoms.sass} +4 -4
  21. package/{templates/_molecules.sass → dist/styles/_05_molecules.sass} +16 -12
  22. package/dist/styles/_06_recipes.sass +189 -0
  23. package/dist/styles/{_base.sass → _07_base.sass} +3 -2
  24. package/dist/styles/_08_blocks.sass +433 -0
  25. package/dist/styles/{_utilities.sass → _09_utilities.sass} +96 -16
  26. package/dist/styles/_10_layouts.sass +373 -0
  27. package/dist/styles/_11_own.sass +21 -0
  28. package/dist/styles/_fractals.sass +7 -6
  29. package/dist/styles/index.sass +14 -16
  30. package/mcp.json +11 -0
  31. package/package.json +6 -3
  32. package/plugin.json +22 -0
  33. package/skills/fractal-styler/SKILL.md +83 -0
  34. package/skills/fractal-styler/references/fractals.md +28 -0
  35. package/skills/fractal-styler/references/tokens.md +36 -0
  36. package/skills/style-migration/SKILL.md +45 -0
  37. package/templates/_00_tokens.sass +177 -0
  38. package/{dist/styles/_config.sass → templates/_01_config.sass} +11 -5
  39. package/templates/_02_fonts.sass +13 -0
  40. package/templates/_03_responsive.sass +31 -0
  41. package/templates/{_atoms.sass → _04_atoms.sass} +4 -4
  42. package/{dist/styles/_molecules.sass → templates/_05_molecules.sass} +16 -12
  43. package/templates/_06_recipes.sass +189 -0
  44. package/templates/{_base.sass → _07_base.sass} +3 -2
  45. package/templates/_08_blocks.sass +433 -0
  46. package/templates/{_utilities.sass → _09_utilities.sass} +96 -16
  47. package/templates/_10_layouts.sass +373 -0
  48. package/templates/_11_own.sass +21 -0
  49. package/templates/_fractals.sass +7 -6
  50. package/templates/index.sass +14 -16
  51. package/dist/styles/_blocks.sass +0 -88
  52. package/dist/styles/_layouts.sass +0 -108
  53. package/dist/styles/_responsive.sass +0 -43
  54. package/dist/styles/_tokens.sass +0 -127
  55. package/templates/_blocks.sass +0 -88
  56. package/templates/_layouts.sass +0 -108
  57. package/templates/_responsive.sass +0 -43
  58. package/templates/_tokens.sass +0 -127
package/README.md CHANGED
@@ -1,15 +1,14 @@
1
1
  # fractalstyler2
2
2
 
3
- A fractal-composition styling system for SvelteKit. **Every style unit is a SASS
4
- mixin ("a fractal"), and components and layouts are recipes of smaller fractals.**
3
+ A fractal-composition styling system for SvelteKit. **Every style unit is a SASS mixin ("a fractal"), and components and layouts are recipes of smaller fractals.**
5
4
 
6
- Use it either as a **shadcn-style scaffolder** (copying editable SASS into your project's `src/lib/styles`) or as a **direct package dependency**.
5
+ Use it either as a **shadcn-style scaffolder** (copying editable SASS directly into your project's `src/lib/styles`) or as a **direct package dependency**.
7
6
 
8
7
  ---
9
8
 
10
9
  ## Quickstart (shadcn-style Scaffolding)
11
10
 
12
- Scaffold the complete, customizable SASS design system directly into your project's `src/lib/styles`:
11
+ Scaffold the complete, customizable SASS design system directly into your project:
13
12
 
14
13
  ```bash
15
14
  # Scaffold into src/lib/styles
@@ -21,22 +20,27 @@ pnpm dlx fractalstyler2 init
21
20
 
22
21
  ### Next Steps in Your Project
23
22
 
24
- **1. Import the stylesheet in your root `+layout.svelte`:**
23
+ **1. Import the stylesheet once globally in your root `src/routes/+layout.svelte`:**
25
24
  ```svelte
26
25
  <script>
27
26
  import '$lib/styles/index.sass';
28
27
  </script>
29
28
  ```
30
29
 
31
- **2. Compose your components using the fractals:**
30
+ **2. Compose your components using the pure mixin barrel:**
32
31
  ```svelte
32
+ <div class="pricing-card">
33
+ <span class="badge" data-status="released">Pro Plan</span>
34
+ <h3>$29/mo</h3>
35
+ <p>Full access to all fractal components and layouts.</p>
36
+ </div>
37
+
33
38
  <style lang="sass">
34
39
  @use '$lib/styles/fractals' as *
35
40
 
36
41
  .pricing-card
37
- +surface(surface, l, 16, md) // bg + border + radius + pad + shadow
38
- +stack(m, center) // flex-column + gap + centered
39
- text-align: center
42
+ +surface(surface, m, 6, md) // bg + border + radius(6px) + padding + shadow
43
+ +stack(s, start) // flex-column + gap(s) + top-anchored flow
40
44
  </style>
41
45
  ```
42
46
 
@@ -47,15 +51,7 @@ pnpm dlx fractalstyler2 init
47
51
  If you prefer importing from `node_modules` instead of scaffolding local files:
48
52
 
49
53
  ```bash
50
- npm install fractalstyler2
51
- # or
52
54
  pnpm add fractalstyler2
53
- ```
54
-
55
- Your app also needs `sass`:
56
- ```bash
57
- npm install -D sass
58
- # or
59
55
  pnpm add -D sass
60
56
  ```
61
57
 
@@ -70,37 +66,54 @@ pnpm add -D sass
70
66
  @use 'fractalstyler2/fractals' as *
71
67
 
72
68
  .card
73
- +surface(surface, s, 12)
69
+ +surface(surface, s, 6)
74
70
  +stack(s)
75
71
  </style>
76
72
  ```
77
73
 
78
74
  ---
79
75
 
80
- ## The Model
76
+ ## The Physical Scale Hierarchy
77
+
78
+ The design system files in `src/lib/styles/` are numbered sequentially from indivisible math to page layouts:
81
79
 
82
- A fractal is a mixin: a tiny reusable styling decision that composes other
83
- fractals. They form four self-similar tiers each tier is "a recipe of the one
84
- below":
80
+ ```
81
+ index.sass ──► Master Entrypoint (Forwards fractals + loads CSS cascade)
82
+ _fractals.sass ──► Pure Mixin Barrel (Emits 0 bytes CSS)
83
+
84
+ ── Phase 1: Pure Functions & Math (Zero CSS Emitted) ─────────────────────────
85
+ _00_tokens.sass ──► Raw CSS custom properties on :root & theme modes
86
+ _01_config.sass ──► Scales, maps, resolvers (space, radius, surface, ink)
87
+ _02_fonts.sass ──► Local @font-face declarations
88
+ _03_responsive.sass ──► Breakpoint helpers (+at, +below, +between)
89
+ _04_atoms.sass ──► Single-decision primitives (+box, +row, +bg, +ink, +pad, +gap)
90
+ _05_molecules.sass ──► Compositions of atoms (+stack, +cluster, +surface, +cols)
91
+ _06_recipes.sass ──► Macro component archetypes (=control, =select, =card, =partition)
92
+
93
+ ── Phase 2: CSS Cascade Emitters (Loaded once globally by index.sass) ─────────
94
+ _07_base.sass ──► Global HTML element resets
95
+ _08_blocks.sass ──► Semantic component classes (.surface, .panel, .select, .badge)
96
+ _09_utilities.sass ──► 1:1 atomic markup projections (.pad-*, .pad-top-*, .gap-*, .hide-desktop)
97
+ _10_layouts.sass ──► Page layout templates (.docs, .card-grid, .hero, .holy-grail)
98
+ _11_own.sass ──► Bespoke local project overrides
99
+ ```
85
100
 
86
- | Tier | What | Examples |
87
- | --- | --- | --- |
88
- | **Config** | scales-as-data + resolvers | `space()`, `radius()`, `align()`, `$breakpoints` |
89
- | **Atoms** | one decision each | `+box` `+row` `+gap` `+pad` `+border` `+radius` `+bg` `+ink` `+type` `+sticky` |
90
- | **Molecules** | graphs of atoms | `+stack` `+cluster` `+cover` `+frame` `+surface` `+cols` `+auto-grid` |
91
- | **Components / Layouts** | graphs of molecules | `.card` `.button` · `.grid-3` `.hero` `.holy-grail` `.docs` `.app-shell` |
101
+ ---
92
102
 
93
- The one idea that makes it click:
103
+ ## The Strict 21-Token Contract
94
104
 
95
- > **A utility class and a semantic component are the same fractal, consumed two ways.**
96
- > `.gap-m { +gap(m) }` binds the fractal to markup; `.hero { +cover; +stack(m) }`
97
- > composes it into a component. One vocabulary, you pick where each is used.
105
+ All themes and surface colors resolve from the 21 variables defined in `_00_tokens.sass`:
106
+
107
+ - **Surfaces**: `--bg`, `--bg-surface`, `--bg-raised`, `--bg-panel`, `--bg-footer`, `--bg-popover`, `--bg-dialog`, `--bg-terminal`, `--bg-input`, `--bg-canvas`
108
+ - **Text & Ink**: `--text-primary`, `--text-secondary`, `--text-muted`, `--text-inverse`
109
+ - **States & Feedback**: `--state-hover`, `--state-hover-subtle`, `--state-selected`
110
+ - **Borders & Accents**: `--border`, `--border-subtle`, `--theme-color`, `--theme-color-alt` *(aliased to `--theme`)*
98
111
 
99
112
  ---
100
113
 
101
114
  ## Color Mode
102
115
 
103
- Light is the marker-free default (SSR-safe). Dark comes from `prefers-color-scheme` and from an explicit `data-mode="dark"` on `<html>`:
116
+ Light is the marker-free default (SSR-safe). Dark mode is activated via `prefers-color-scheme: dark` or explicitly via `data-mode="dark"` on `<html>`:
104
117
 
105
118
  ```js
106
119
  import { toggleMode, setMode } from 'fractalstyler2';
@@ -110,31 +123,20 @@ setMode('dark'); // force mode
110
123
 
111
124
  ---
112
125
 
113
- ## CLI & MCP Server
114
-
115
- ### Scaffolder CLI
116
- ```bash
117
- fractalstyler2 init [dest] [options]
118
-
119
- Arguments:
120
- dest Target directory for SASS partials (default: src/lib/styles)
121
-
122
- Options:
123
- -f, --force Overwrite files if they already exist
124
- -h, --help Show help message
125
- ```
126
-
127
- ### Model Context Protocol (MCP) Server
128
- Use `fractalstyler2` directly with AI canvas tools (e.g. **OpenDesign**, **Pencil**), IDEs (**Cursor**, **Antigravity**), and assistants (**Claude Desktop**):
129
-
130
- ```bash
131
- # Start MCP server over stdio
132
- npx fractalstyler2-mcp
133
- # or
134
- npx fractalstyler2 mcp
135
- ```
136
-
137
- Exposes tools to compile fractals to live CSS, snap arbitrary canvas values to Utopia tokens, generate Svelte 5 + SASS components, and lint recipes. See [docs/10-mcp-server.md](docs/10-mcp-server.md) for configuration details.
126
+ ## Documentation Index
127
+
128
+ | Guide | Description |
129
+ |---|---|
130
+ | [01. Philosophy](docs/01-philosophy.md) | The fractal model, self-similarity, and dual consumption |
131
+ | [02. Structure](docs/02-structure.md) | File anatomy, the 12-file numbered scale, and cascade order |
132
+ | [03. Getting Started](docs/03-getting-started.md) | Scaffolding, imports, and wiring into SvelteKit |
133
+ | [04. Fractals Reference](docs/04-fractals-reference.md) | Comprehensive reference for every atom and molecule mixin |
134
+ | [05. Tokens & Theming](docs/05-tokens-and-theming.md) | Fluid scales, the 21-variable contract, and dark mode |
135
+ | [06. Utilities Reference](docs/06-utilities.md) | Generated atomic classes, directional padding, and visibility |
136
+ | [07. Components & Layouts](docs/07-components-and-layouts.md) | Shipped blocks, cards, and page layout templates |
137
+ | [08. Recipes & Patterns](docs/08-recipes.md) | Worked examples: pricing card, responsive docs shell, dialog |
138
+ | [09. Migration from v1](docs/09-migration-from-v1.md) | Upgrading from older unnumbered stylesheets |
139
+ | [DESIGN.md](DESIGN.md) | Golden UI invariants, card containment laws, and defect prevention |
138
140
 
139
141
  ---
140
142
 
package/dist/cli.js CHANGED
@@ -23,19 +23,24 @@ fractalstyler2 — SASS fractal design system scaffolder & MCP server
23
23
  Usage:
24
24
  npx fractalstyler2 init [dest] [options]
25
25
  npx fractalstyler2 mcp
26
+ npx fractalstyler2 mcp:install
27
+ npx fractalstyler2 mcp:export [dest]
26
28
 
27
29
  Commands:
28
- init [dest] Scaffold SASS partials into target directory (default: src/lib/styles)
29
- mcp Start the Model Context Protocol (MCP) server for OpenDesign, Claude, etc.
30
+ init [dest] Scaffold SASS partials into target directory (default: src/lib/styles)
31
+ mcp Start the Model Context Protocol (MCP) server for OpenDesign, Claude, etc.
32
+ mcp:install Automatically install MCP schemas & config into Antigravity & OpenCode
33
+ mcp:export [dest] Export static MCP tool schema JSON files to target directory (default: .mcp)
30
34
 
31
35
  Options:
32
- -f, --force Overwrite files if they already exist
33
- -h, --help Show this help message
36
+ -f, --force Overwrite files if they already exist
37
+ -h, --help Show this help message
34
38
 
35
39
  Examples:
36
40
  npx fractalstyler2 init
37
- npx fractalstyler2 init src/lib/styles --force
38
41
  npx fractalstyler2 mcp
42
+ npx fractalstyler2 mcp:install
43
+ npx fractalstyler2 mcp:export ~/.gemini/antigravity/mcp/fractalstyler2
39
44
  `);
40
45
  }
41
46
  function init(destArg, force) {
@@ -84,7 +89,7 @@ function init(destArg, force) {
84
89
  @use '${fractalsPath}' as *
85
90
 
86
91
  .card
87
- +surface(surface, s, 12)
92
+ +surface(surface, s, 6)
88
93
  +stack(s)
89
94
  </style>
90
95
  `);
@@ -94,16 +99,49 @@ const showHelp = args.includes('-h') || args.includes('--help');
94
99
  const force = args.includes('-f') || args.includes('--force');
95
100
  const positional = args.filter((a) => !a.startsWith('-'));
96
101
  const command = positional[0];
97
- if (showHelp || (command && !['init', 'mcp'].includes(command))) {
98
- if (command && !['init', 'mcp'].includes(command)) {
102
+ const VALID_COMMANDS = ['init', 'mcp', 'mcp:export', 'mcp:install'];
103
+ if (showHelp || (command && !VALID_COMMANDS.includes(command))) {
104
+ if (command && !VALID_COMMANDS.includes(command)) {
99
105
  console.error(`Unknown command: ${command}`);
100
106
  }
101
107
  printUsage();
102
- process.exit(command && !['init', 'mcp'].includes(command) ? 1 : 0);
108
+ process.exit(command && !VALID_COMMANDS.includes(command) ? 1 : 0);
103
109
  }
104
110
  else if (command === 'mcp') {
105
111
  import('./mcp/server.js');
106
112
  }
113
+ else if (command === 'mcp:export') {
114
+ import('./mcp/export.js').then(({ exportSchemas }) => {
115
+ const dest = positional[1] || '.mcp/fractalstyler2';
116
+ const { created, dir } = exportSchemas(dest);
117
+ console.log(`\n▲ Exported ${created} MCP schema files to: ${dir}\n`);
118
+ });
119
+ }
120
+ else if (command === 'mcp:install') {
121
+ import('./mcp/export.js').then(({ installToAntigravity, installToOpenCode }) => {
122
+ console.log(`\n▲ Installing fractalstyler2 MCP schemas & configuration...\n`);
123
+ try {
124
+ const agy = installToAntigravity();
125
+ console.log(` \x1b[32m✔\x1b[0m Antigravity MCP schemas: ${agy.dir}`);
126
+ }
127
+ catch (e) {
128
+ console.log(` \x1b[90m-\x1b[0m Antigravity install skipped (${e.message})`);
129
+ }
130
+ try {
131
+ const oc = installToOpenCode();
132
+ if (oc.success) {
133
+ console.log(` \x1b[32m✔\x1b[0m OpenCode MCP configured: ${oc.configPath}`);
134
+ }
135
+ else {
136
+ console.log(` \x1b[90m-\x1b[0m OpenCode config not found (skipped)`);
137
+ }
138
+ }
139
+ catch (e) {
140
+ console.log(` \x1b[90m-\x1b[0m OpenCode install skipped (${e.message})`);
141
+ }
142
+ console.log(`\nDone! fractalstyler2 MCP is ready.\n`);
143
+ });
144
+ }
107
145
  else if (command === 'init') {
108
146
  init(positional[1], force);
109
147
  }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,37 @@
1
- export declare const version = "0.0.1";
1
+ export declare const version = "0.3.0";
2
2
  export type Mode = 'light' | 'dark';
3
3
  /** Set the color mode by writing the [data-mode] marker on <html>. */
4
4
  export declare function setMode(mode: Mode): void;
5
5
  /** Toggle between light and dark, returning the new mode. */
6
6
  export declare function toggleMode(): Mode;
7
+ export declare const breakpoints: {
8
+ readonly sm: "640px";
9
+ readonly md: "768px";
10
+ readonly lg: "1024px";
11
+ readonly xl: "1240px";
12
+ };
13
+ export declare const spaceScale: readonly ["3xs", "2xs", "xs", "s", "m", "l", "xl", "2xl", "3xl", "s-l"];
14
+ export declare const typographyScale: readonly ["xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl"];
15
+ export declare const radiusSteps: readonly ["0", "2", "3", "4", "6", "8", "12", "16", "24", "full"];
16
+ export declare const surfaceRoles: readonly ["bg", "surface", "raised", "panel", "footer", "popover", "dialog", "terminal", "input", "canvas"];
17
+ export declare const inkRoles: readonly ["primary", "secondary", "muted", "inverse", "theme-color", "theme-color-alt"];
18
+ export declare const tokens: {
19
+ readonly version: "0.3.0";
20
+ readonly breakpoints: {
21
+ readonly sm: "640px";
22
+ readonly md: "768px";
23
+ readonly lg: "1024px";
24
+ readonly xl: "1240px";
25
+ };
26
+ readonly spaceScale: readonly ["3xs", "2xs", "xs", "s", "m", "l", "xl", "2xl", "3xl", "s-l"];
27
+ readonly typographyScale: readonly ["xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl"];
28
+ readonly radiusSteps: readonly ["0", "2", "3", "4", "6", "8", "12", "16", "24", "full"];
29
+ readonly surfaceRoles: readonly ["bg", "surface", "raised", "panel", "footer", "popover", "dialog", "terminal", "input", "canvas"];
30
+ readonly inkRoles: readonly ["primary", "secondary", "muted", "inverse", "theme-color", "theme-color-alt"];
31
+ };
32
+ export type Breakpoint = keyof typeof breakpoints;
33
+ export type SpaceStep = (typeof spaceScale)[number];
34
+ export type TypographyStep = (typeof typographyScale)[number];
35
+ export type RadiusStep = (typeof radiusSteps)[number];
36
+ export type SurfaceRole = (typeof surfaceRoles)[number];
37
+ export type InkRole = (typeof inkRoles)[number];
package/dist/index.js CHANGED
@@ -1,12 +1,11 @@
1
1
  // fractalstyler2 — a fractal-composition styling system for SvelteKit.
2
2
  //
3
- // The product is the SASS in ./fractals and ./components, surfaced as:
3
+ // The product is the SASS in ./fractals and ./styles, surfaced as:
4
4
  // import 'fractalstyler2/styles' // emit the full stylesheet
5
5
  // @use 'fractalstyler2/fractals' as * // compose your own with the mixins
6
6
  //
7
- // This entry ships only tiny runtime helpers. There is deliberately no CSS-in-JS
8
- // and no component coupling — the styling layer is framework-agnostic SASS.
9
- export const version = '0.0.1';
7
+ // This entry ships runtime helpers and token metadata.
8
+ export const version = '0.3.0';
10
9
  /** Set the color mode by writing the [data-mode] marker on <html>. */
11
10
  export function setMode(mode) {
12
11
  if (typeof document === 'undefined')
@@ -20,3 +19,73 @@ export function toggleMode() {
20
19
  setMode(next);
21
20
  return next;
22
21
  }
22
+ // Design Token Metadata
23
+ export const breakpoints = {
24
+ sm: '640px',
25
+ md: '768px',
26
+ lg: '1024px',
27
+ xl: '1240px'
28
+ };
29
+ export const spaceScale = [
30
+ '3xs',
31
+ '2xs',
32
+ 'xs',
33
+ 's',
34
+ 'm',
35
+ 'l',
36
+ 'xl',
37
+ '2xl',
38
+ '3xl',
39
+ 's-l'
40
+ ];
41
+ export const typographyScale = [
42
+ 'xs',
43
+ 'sm',
44
+ 'md',
45
+ 'lg',
46
+ 'xl',
47
+ '2xl',
48
+ '3xl',
49
+ '4xl'
50
+ ];
51
+ export const radiusSteps = [
52
+ '0',
53
+ '2',
54
+ '3',
55
+ '4',
56
+ '6',
57
+ '8',
58
+ '12',
59
+ '16',
60
+ '24',
61
+ 'full'
62
+ ];
63
+ export const surfaceRoles = [
64
+ 'bg',
65
+ 'surface',
66
+ 'raised',
67
+ 'panel',
68
+ 'footer',
69
+ 'popover',
70
+ 'dialog',
71
+ 'terminal',
72
+ 'input',
73
+ 'canvas'
74
+ ];
75
+ export const inkRoles = [
76
+ 'primary',
77
+ 'secondary',
78
+ 'muted',
79
+ 'inverse',
80
+ 'theme-color',
81
+ 'theme-color-alt'
82
+ ];
83
+ export const tokens = {
84
+ version,
85
+ breakpoints,
86
+ spaceScale,
87
+ typographyScale,
88
+ radiusSteps,
89
+ surfaceRoles,
90
+ inkRoles
91
+ };
@@ -0,0 +1,13 @@
1
+ export declare function getSchemasDir(): string;
2
+ export declare function exportSchemas(targetDir: string): {
3
+ created: number;
4
+ dir: string;
5
+ };
6
+ export declare function installToAntigravity(): {
7
+ success: boolean;
8
+ dir: string;
9
+ };
10
+ export declare function installToOpenCode(): {
11
+ success: boolean;
12
+ configPath: string;
13
+ };
@@ -0,0 +1,76 @@
1
+ import { existsSync, mkdirSync, copyFileSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import os from 'node:os';
5
+ export function getSchemasDir() {
6
+ const HERE = dirname(fileURLToPath(import.meta.url));
7
+ const candidates = [
8
+ join(HERE, 'schemas'),
9
+ join(HERE, '..', 'mcp', 'schemas'),
10
+ join(HERE, '..', '..', 'src', 'lib', 'mcp', 'schemas'),
11
+ join(process.cwd(), 'src', 'lib', 'mcp', 'schemas'),
12
+ join(process.cwd(), 'dist', 'mcp', 'schemas')
13
+ ];
14
+ for (const candidate of candidates) {
15
+ if (existsSync(candidate))
16
+ return candidate;
17
+ }
18
+ throw new Error(`Schemas directory not found. Searched: ${candidates.join(', ')}`);
19
+ }
20
+ export function exportSchemas(targetDir) {
21
+ const resolvedTarget = resolve(process.cwd(), targetDir);
22
+ mkdirSync(resolvedTarget, { recursive: true });
23
+ const schemasDir = getSchemasDir();
24
+ const files = readdirSync(schemasDir);
25
+ let created = 0;
26
+ for (const file of files) {
27
+ const srcFile = join(schemasDir, file);
28
+ const destFile = join(resolvedTarget, file);
29
+ copyFileSync(srcFile, destFile);
30
+ created++;
31
+ }
32
+ return { created, dir: resolvedTarget };
33
+ }
34
+ export function installToAntigravity() {
35
+ const home = os.homedir();
36
+ const agyMcpDir = join(home, '.gemini', 'antigravity', 'mcp', 'fractalstyler2');
37
+ const agyConfigPath = join(home, '.gemini', 'antigravity', 'mcp_config.json');
38
+ exportSchemas(agyMcpDir);
39
+ // Update mcp_config.json if it exists or create it
40
+ let config = { mcpServers: {} };
41
+ if (existsSync(agyConfigPath)) {
42
+ try {
43
+ config = JSON.parse(readFileSync(agyConfigPath, 'utf8'));
44
+ }
45
+ catch { }
46
+ }
47
+ if (!config.mcpServers)
48
+ config.mcpServers = {};
49
+ config.mcpServers.fractalstyler2 = {
50
+ command: 'node',
51
+ args: [join(dirname(fileURLToPath(import.meta.url)), 'server.js')],
52
+ env: {}
53
+ };
54
+ writeFileSync(agyConfigPath, JSON.stringify(config, null, 2), 'utf8');
55
+ return { success: true, dir: agyMcpDir };
56
+ }
57
+ export function installToOpenCode() {
58
+ const home = os.homedir();
59
+ const ocConfigPath = join(home, '.config', 'opencode', 'opencode.json');
60
+ if (existsSync(ocConfigPath)) {
61
+ try {
62
+ const config = JSON.parse(readFileSync(ocConfigPath, 'utf8'));
63
+ if (!config.mcp)
64
+ config.mcp = {};
65
+ config.mcp.fractalstyler2 = {
66
+ type: 'local',
67
+ command: ['node', join(dirname(fileURLToPath(import.meta.url)), 'server.js')],
68
+ enabled: true
69
+ };
70
+ writeFileSync(ocConfigPath, JSON.stringify(config, null, 2), 'utf8');
71
+ return { success: true, configPath: ocConfigPath };
72
+ }
73
+ catch { }
74
+ }
75
+ return { success: false, configPath: ocConfigPath };
76
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "compile_fractals",
3
+ "description": "Compiles indented SASS fractal mixins into CSS. Useful for live preview in OpenDesign, web apps, or verifying style output.",
4
+ "parameters": {
5
+ "type": "object",
6
+ "properties": {
7
+ "sassCode": {
8
+ "type": "string",
9
+ "description": "Indented SASS code. Can use any fractal mixin (+surface, +stack, +gap, etc.)."
10
+ },
11
+ "className": {
12
+ "type": "string",
13
+ "description": "Optional CSS class name to wrap the mixins under (e.g. 'preview-card'). Defaults to 'element'."
14
+ }
15
+ },
16
+ "required": [
17
+ "sassCode"
18
+ ]
19
+ }
20
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "css_to_fractals",
3
+ "description": "Converts raw CSS declarations (from Figma/OpenDesign inspection) into idiomatic fractalstyler2 SASS mixin recipes (+surface, +stack, +cluster, etc.).",
4
+ "parameters": {
5
+ "type": "object",
6
+ "properties": {
7
+ "css": {
8
+ "type": "string",
9
+ "description": "Raw CSS block or declaration lines"
10
+ }
11
+ },
12
+ "required": [
13
+ "css"
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "generate_component",
3
+ "description": "Generates a production-ready Svelte 5 component with runes and scoped SASS fractal mixins.",
4
+ "parameters": {
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "Component name (e.g. PricingCard, UserAvatar, HeroBanner)"
10
+ },
11
+ "type": {
12
+ "type": "string",
13
+ "enum": [
14
+ "card",
15
+ "panel",
16
+ "button",
17
+ "badge",
18
+ "modal",
19
+ "hero",
20
+ "nav",
21
+ "custom"
22
+ ],
23
+ "description": "Type of component recipe."
24
+ },
25
+ "elevation": {
26
+ "type": "string",
27
+ "enum": [
28
+ "none",
29
+ "sm",
30
+ "md",
31
+ "lg"
32
+ ],
33
+ "description": "Surface elevation."
34
+ },
35
+ "description": {
36
+ "type": "string",
37
+ "description": "Detailed description of component purpose and props."
38
+ }
39
+ },
40
+ "required": [
41
+ "name",
42
+ "type"
43
+ ]
44
+ }
45
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "get_design_tokens",
3
+ "description": "Returns the complete structured JSON design tokens (fluid Utopia space scales, typography, radii, shadows, surfaces, ink colors, breakpoints).",
4
+ "parameters": {
5
+ "type": "object",
6
+ "properties": {
7
+ "category": {
8
+ "type": "string",
9
+ "enum": [
10
+ "all",
11
+ "space",
12
+ "typography",
13
+ "radius",
14
+ "shadows",
15
+ "surfaces",
16
+ "ink",
17
+ "breakpoints"
18
+ ],
19
+ "description": "Optional category filter (all, space, typography, radius, shadows, surfaces, ink, breakpoints). Defaults to 'all'."
20
+ }
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,18 @@
1
+ # fractalstyler2 MCP Server
2
+
3
+ The fractalstyler2 MCP server provides tools to inspect design tokens, snap canvas pixel values to Utopia tokens, compile indented SASS fractal mixins to live CSS, generate Svelte 5 runes components with scoped SASS, and lint style recipes.
4
+
5
+ ## Available Tools:
6
+ 1. **compile_fractals**: Compiles indented SASS fractal mixins (+surface, +stack, +gap, etc.) into live CSS.
7
+ 2. **get_design_tokens**: Returns structured JSON for fluid space scale (3xs..3xl), typography, radii, shadows, surfaces, and ink roles.
8
+ 3. **snap_to_tokens**: Snaps raw pixel measurements (gap, padding, radius, fontSize) from canvas/inspection to the closest design tokens.
9
+ 4. **css_to_fractals**: Converts raw CSS declarations into idiomatic fractal mixin recipes.
10
+ 5. **generate_component**: Generates complete Svelte 5 components with runes and scoped SASS fractals.
11
+ 6. **validate_recipe**: Lints code against golden rules (flags legacy v1 classes like gap8/pad16, hardcoded pixels, modifier classes).
12
+ 7. **list_fractals**: Catalogs all atom & molecule mixins with signatures.
13
+
14
+ ## Golden Rules:
15
+ - Never hardcode values that tokens cover; use `+gap(m)`, `+radius(6)`, `+bg(surface)`.
16
+ - Compose fractals (`+surface`, `+stack`, `+cluster`); write raw CSS only for unique lines.
17
+ - Express component state on `data-*` / `aria-*` attributes, never modifier classes.
18
+ - No legacy v1 classes (e.g. `gap8`, `pad16`, `w100`, `.stack` in markup).
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "list_fractals",
3
+ "description": "Returns the catalog of all available atom & molecule mixins and layout templates with their signatures and descriptions.",
4
+ "parameters": {
5
+ "type": "object",
6
+ "properties": {
7
+ "tier": {
8
+ "type": "string",
9
+ "enum": [
10
+ "all",
11
+ "atoms",
12
+ "molecules",
13
+ "recipes",
14
+ "layouts"
15
+ ],
16
+ "description": "Filter by fractal tier (all, atoms, molecules, recipes, layouts)."
17
+ }
18
+ }
19
+ }
20
+ }