fractalstyler2 0.0.1 → 0.1.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
@@ -3,62 +3,35 @@
3
3
  A fractal-composition styling system for SvelteKit. **Every style unit is a SASS
4
4
  mixin ("a fractal"), and components and layouts are recipes of smaller fractals.**
5
5
 
6
- This is a standalone package with no relationship to any earlier styler. The
7
- product is framework-agnostic SASS surfaced through a SvelteKit library; the JS
8
- runtime is just a tiny mode helper.
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**.
9
7
 
10
- ## The idea
8
+ ---
11
9
 
12
- A fractal is a mixin: a tiny reusable styling decision that composes other
13
- fractals. They form four self-similar tiers — each tier is "a recipe of the one
14
- below":
15
-
16
- | Tier | What | Examples |
17
- | --- | --- | --- |
18
- | **Config** | scales-as-data + resolvers | `space()`, `radius()`, `align()`, `$breakpoints` |
19
- | **Atoms** | one decision each | `+box` `+row` `+gap` `+pad` `+border` `+radius` `+bg` `+ink` `+type` `+sticky` |
20
- | **Molecules** | graphs of atoms | `+stack` `+cluster` `+cover` `+frame` `+surface` `+cols` `+auto-grid` |
21
- | **Components / Layouts** | graphs of molecules | `.card` `.button` · `.grid-3` `.hero` `.holy-grail` `.docs` `.app-shell` |
10
+ ## Quickstart (shadcn-style Scaffolding)
22
11
 
23
- The one idea that makes it click:
24
-
25
- > **A utility class and a semantic component are the same fractal, consumed two ways.**
26
- > `.gap-m { +gap(m) }` binds the fractal to markup; `.hero { +cover; +stack(m) }`
27
- > composes it into a component. One vocabulary, you pick where each is used.
28
-
29
- ## Install
12
+ Scaffold the complete, customizable SASS design system directly into your project's `src/lib/styles`:
30
13
 
31
14
  ```bash
32
- pnpm add fractalstyler2
33
- ```
15
+ # Scaffold into src/lib/styles
16
+ npx fractalstyler2 init
34
17
 
35
- ## Use
18
+ # Or using pnpm
19
+ pnpm dlx fractalstyler2 init
20
+ ```
36
21
 
37
- **1 Emit the ready-made stylesheet** (tokens, base reset, utility classes,
38
- blocks, layouts). Import once, globally (e.g. in your root `+layout.svelte`):
22
+ ### Next Steps in Your Project
39
23
 
24
+ **1. Import the stylesheet in your root `+layout.svelte`:**
40
25
  ```svelte
41
26
  <script>
42
- import 'fractalstyler2/styles';
27
+ import '$lib/styles/index.sass';
43
28
  </script>
44
29
  ```
45
30
 
46
- Then write thin, semantic markup:
47
-
48
- ```svelte
49
- <div class="grid-3">
50
- <article class="card"><h3 class="text-lg">Composable</h3></article>
51
- <article class="card" data-elevated><h3 class="text-lg">Elevated</h3></article>
52
- <article class="card"><h3 class="text-lg">Semantic</h3></article>
53
- </div>
54
- ```
55
-
56
- **2 — Compose your own components from the fractals.** Import the pure API
57
- (emits nothing until called) inside any component's SASS:
58
-
31
+ **2. Compose your components using the fractals:**
59
32
  ```svelte
60
33
  <style lang="sass">
61
- @use 'fractalstyler2/fractals' as *
34
+ @use '$lib/styles/fractals' as *
62
35
 
63
36
  .pricing-card
64
37
  +surface(surface, l, 16, md) // bg + border + radius + pad + shadow
@@ -67,48 +40,104 @@ Then write thin, semantic markup:
67
40
  </style>
68
41
  ```
69
42
 
70
- Values prefer the finite token scale and fall back to raw units in the same
71
- call: `+gap(m)` → `var(--space-m)`, `+gap(16)` → `16px`. No JIT class explosion.
43
+ ---
44
+
45
+ ## Alternative: Direct Package Dependency
72
46
 
73
- ## What ships
47
+ If you prefer importing from `node_modules` instead of scaffolding local files:
74
48
 
49
+ ```bash
50
+ npm install fractalstyler2
51
+ # or
52
+ pnpm add fractalstyler2
75
53
  ```
76
- fractalstyler2/
77
- ├─ styles → the full emitted stylesheet (import 'fractalstyler2/styles')
78
- ├─ fractals → the mixin/function API (@use 'fractalstyler2/fractals' as *)
79
- ├─ tokens → just the custom properties (@use 'fractalstyler2/tokens')
80
- └─ (default) → { version, setMode, toggleMode }
54
+
55
+ Your app also needs `sass`:
56
+ ```bash
57
+ npm install -D sass
58
+ # or
59
+ pnpm add -D sass
81
60
  ```
82
61
 
83
- Source layout: `src/lib/fractals/` (config, tokens, base, responsive, atoms,
84
- molecules, utilities), `src/lib/components/` (blocks, layouts),
85
- `src/lib/styles/` (the emit entry).
62
+ ### Use from `node_modules`:
86
63
 
87
- ## Color mode
64
+ ```svelte
65
+ <script>
66
+ import 'fractalstyler2/styles';
67
+ </script>
88
68
 
89
- Light is the marker-free default (SSR-safe). Dark comes from
90
- `prefers-color-scheme` and from an explicit `data-mode="dark"` on `<html>`:
69
+ <style lang="sass">
70
+ @use 'fractalstyler2/fractals' as *
71
+
72
+ .card
73
+ +surface(surface, s, 12)
74
+ +stack(s)
75
+ </style>
76
+ ```
77
+
78
+ ---
79
+
80
+ ## The Model
81
+
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":
85
+
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` |
92
+
93
+ The one idea that makes it click:
94
+
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.
98
+
99
+ ---
100
+
101
+ ## Color Mode
102
+
103
+ Light is the marker-free default (SSR-safe). Dark comes from `prefers-color-scheme` and from an explicit `data-mode="dark"` on `<html>`:
91
104
 
92
105
  ```js
93
106
  import { toggleMode, setMode } from 'fractalstyler2';
94
107
  toggleMode(); // flip light/dark
95
- setMode('dark'); // force
108
+ setMode('dark'); // force mode
96
109
  ```
97
110
 
98
- ## Included layouts
111
+ ---
112
+
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)
99
121
 
100
- `.grid-3` (responsive 1→2→3), `.card-grid` (intrinsic auto-fit), `.hero`,
101
- `.holy-grail`, `.docs`, `.app-shell` each a few fractal calls in
102
- `src/lib/components/_layouts.sass`.
122
+ Options:
123
+ -f, --force Overwrite files if they already exist
124
+ -h, --help Show help message
125
+ ```
103
126
 
104
- ## Develop
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**):
105
129
 
106
130
  ```bash
107
- pnpm install
108
- pnpm dev # demo showcase at /
109
- pnpm run prepack # build the distributable package into dist/
131
+ # Start MCP server over stdio
132
+ npx fractalstyler2-mcp
133
+ # or
134
+ npx fractalstyler2 mcp
110
135
  ```
111
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.
138
+
139
+ ---
140
+
112
141
  ## License
113
142
 
114
143
  MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, mkdirSync, readdirSync, copyFileSync } from 'node:fs';
3
+ import { dirname, join, resolve, relative } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import process from 'node:process';
6
+ function getTemplatesDir() {
7
+ const HERE = dirname(fileURLToPath(import.meta.url));
8
+ const candidates = [
9
+ join(HERE, '..', 'templates'),
10
+ join(HERE, '..', '..', 'templates'),
11
+ join(HERE, 'templates')
12
+ ];
13
+ for (const candidate of candidates) {
14
+ if (existsSync(candidate))
15
+ return candidate;
16
+ }
17
+ throw new Error(`Templates directory not found. Searched in: ${candidates.join(', ')}`);
18
+ }
19
+ function printUsage() {
20
+ console.log(`
21
+ fractalstyler2 — SASS fractal design system scaffolder & MCP server
22
+
23
+ Usage:
24
+ npx fractalstyler2 init [dest] [options]
25
+ npx fractalstyler2 mcp
26
+
27
+ 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
+
31
+ Options:
32
+ -f, --force Overwrite files if they already exist
33
+ -h, --help Show this help message
34
+
35
+ Examples:
36
+ npx fractalstyler2 init
37
+ npx fractalstyler2 init src/lib/styles --force
38
+ npx fractalstyler2 mcp
39
+ `);
40
+ }
41
+ function init(destArg, force) {
42
+ const dest = destArg ?? 'src/lib/styles';
43
+ const cwd = process.cwd();
44
+ const targetDir = resolve(cwd, dest);
45
+ console.log(`\n▲ fractalstyler2 init\n`);
46
+ console.log(`Scaffolding SASS design system into: ${dest}\n`);
47
+ mkdirSync(targetDir, { recursive: true });
48
+ const templatesDir = getTemplatesDir();
49
+ const files = readdirSync(templatesDir).filter((f) => f.endsWith('.sass'));
50
+ let created = 0;
51
+ let overwritten = 0;
52
+ let skipped = 0;
53
+ for (const file of files) {
54
+ const targetFile = join(targetDir, file);
55
+ const relPath = relative(cwd, targetFile);
56
+ if (existsSync(targetFile)) {
57
+ if (force) {
58
+ copyFileSync(join(templatesDir, file), targetFile);
59
+ console.log(` \x1b[33moverwrite\x1b[0m ${relPath}`);
60
+ overwritten++;
61
+ }
62
+ else {
63
+ console.log(` \x1b[90mskip\x1b[0m ${relPath} (already exists, use --force to overwrite)`);
64
+ skipped++;
65
+ }
66
+ }
67
+ else {
68
+ copyFileSync(join(templatesDir, file), targetFile);
69
+ console.log(` \x1b[32mcreate\x1b[0m ${relPath}`);
70
+ created++;
71
+ }
72
+ }
73
+ console.log(`\nDone: ${created} created, ${overwritten} overwritten, ${skipped} skipped.\n`);
74
+ const importPath = dest === 'src/lib/styles' ? '$lib/styles/index.sass' : `${dest}/index.sass`;
75
+ const fractalsPath = dest === 'src/lib/styles' ? '$lib/styles/fractals' : `${dest}/fractals`;
76
+ console.log(`Next steps:
77
+ 1. Import the stylesheet once globally (e.g. in src/routes/+layout.svelte):
78
+ <script>
79
+ import '${importPath}';
80
+ </script>
81
+
82
+ 2. Compose your components with fractal mixins:
83
+ <style lang="sass">
84
+ @use '${fractalsPath}' as *
85
+
86
+ .card
87
+ +surface(surface, s, 12)
88
+ +stack(s)
89
+ </style>
90
+ `);
91
+ }
92
+ const args = process.argv.slice(2);
93
+ const showHelp = args.includes('-h') || args.includes('--help');
94
+ const force = args.includes('-f') || args.includes('--force');
95
+ const positional = args.filter((a) => !a.startsWith('-'));
96
+ const command = positional[0];
97
+ if (showHelp || (command && !['init', 'mcp'].includes(command))) {
98
+ if (command && !['init', 'mcp'].includes(command)) {
99
+ console.error(`Unknown command: ${command}`);
100
+ }
101
+ printUsage();
102
+ process.exit(command && !['init', 'mcp'].includes(command) ? 1 : 0);
103
+ }
104
+ else if (command === 'mcp') {
105
+ import('./mcp/server.js');
106
+ }
107
+ else if (command === 'init') {
108
+ init(positional[1], force);
109
+ }
110
+ else {
111
+ // Default to init if no subcommand given (e.g., `npx fractalstyler2`)
112
+ init(positional[0], force);
113
+ }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * fractalstyler2 MCP Server
4
+ * Model Context Protocol server exposing design tokens, SASS mixin compilation,
5
+ * token snapping, component generation, and linting for OpenDesign, Claude Desktop, Cursor, etc.
6
+ */
7
+ export {};