swatchkit 0.0.1 → 0.0.3

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
@@ -1,57 +1,93 @@
1
1
  # SwatchKit
2
2
 
3
- **SwatchKit** is a lightweight, zero-configuration tool for creating HTML pattern libraries. It follows the "Magic Folder" principle: you drop files in, and a documentation site comes out.
3
+ **SwatchKit** is a lightweight tool for generating HTML pattern libraries. It acts as a **Pattern Discovery Engine**: it scans your folders for HTML components and stitches them into a documentation site using a layout you control.
4
4
 
5
- ## How it works
5
+ It follows the "Magic Folder" principle: drop files in, and a library comes out.
6
6
 
7
- 1. **Drop Patterns:** Add `.html` files (or folders) to `src/patterns/`.
8
- 2. **Add Styles:** Add standard CSS to `src/css/styles.css`.
9
- 3. **Build:** Run `node build.js`.
7
+ ## Quick Start
10
8
 
11
- ## Features
9
+ Try it instantly in any project:
12
10
 
13
- ### 1. The Magic Folder
14
- * **Single File:** Drop `button.html` into `src/patterns/`. It automatically appears in the library.
15
- * **Component Folder:** Drop a folder like `src/patterns/carousel/` containing `index.html`. It works exactly the same way.
11
+ ```bash
12
+ # 1. Initialize the layout
13
+ npx swatchkit init
16
14
 
17
- ### 2. Automatic JS Bundling
18
- If your component needs client-side JavaScript, just add a `.js` file to its folder.
19
- * Example: `src/patterns/carousel/script.js`
20
- * **SwatchKit** will automatically find it, wrap it in an IIFE (to protect scope), and bundle it into the final site. You can have multiple JS files per pattern.
15
+ # 2. Build the library
16
+ npx swatchkit
17
+ ```
21
18
 
22
- ### 3. Zero Config
23
- No config files. No build pipelines. No complex templating engines. Just HTML, CSS, and JS.
19
+ This will create a `swatches/` folder and build your site to `public/swatchkit/`.
24
20
 
25
- ## Usage
21
+ ---
26
22
 
27
- ### Using npx (Recommended)
23
+ ## Project Setup (Recommended)
28
24
 
29
- Run directly without installing:
30
- ```bash
31
- npx swatchkit
32
- ```
33
-
34
- ### Installing locally
25
+ For real projects, install SwatchKit as a development dependency to lock the version.
35
26
 
36
- Install as a dev dependency:
37
27
  ```bash
38
28
  npm install -D swatchkit
39
29
  ```
40
30
 
41
- Then add to your `package.json` scripts:
31
+ Then add it to your `package.json` scripts:
32
+
42
33
  ```json
43
34
  "scripts": {
44
- "build:patterns": "swatchkit"
35
+ "patterns": "swatchkit"
45
36
  }
46
37
  ```
47
38
 
48
- And run:
39
+ ## How It Works
40
+
41
+ ### 1. The Magic Folder
42
+ By default, SwatchKit looks for a `swatches/` folder in your project root.
43
+ * **Single File:** Drop `card.html` into `swatches/`. It appears in the library.
44
+ * **Component Folder:** Drop a folder like `swatches/carousel/` containing `index.html`. It works the same way.
45
+
46
+ ### 2. Custom Layouts
47
+ When you run `swatchkit init`, we create `swatches/_layout.html`.
48
+ **You own this file.**
49
+ * Add your own `<link rel="stylesheet" href="/css/app.css">`.
50
+ * Add custom fonts, scripts, or meta tags.
51
+ * Change the HTML structure, logo, or classes.
52
+
53
+ SwatchKit simply injects the content into the `<!-- PATTERNS -->` and `<!-- SIDEBAR_LINKS -->` placeholders.
54
+
55
+ ### 3. JavaScript Bundling
56
+ If your component needs client-side JS:
57
+ 1. Create a folder: `swatches/carousel/`.
58
+ 2. Add `index.html` (Markup).
59
+ 3. Add `script.js` (Logic).
60
+
61
+ SwatchKit automatically bundles your JS files, wraps them in a safety scope (IIFE), and injects them into the final build.
62
+
63
+ ## CLI Reference
64
+
49
65
  ```bash
50
- npm run build:patterns
66
+ swatchkit [command] [options]
51
67
  ```
52
68
 
53
- ### View the library
54
- After building, open the generated file:
55
- ```bash
56
- open dist/index.html
69
+ ### Commands
70
+ * `swatchkit` (Default): Builds the library.
71
+ * `swatchkit init`: Scaffolds the `_layout.html` file.
72
+
73
+ ### Flags
74
+ | Flag | Short | Description |
75
+ | :--- | :--- | :--- |
76
+ | `--watch` | `-w` | Watch mode (coming soon). |
77
+ | `--config` | `-c` | Path to config file. |
78
+ | `--input` | `-i` | Pattern directory (Default: `swatches/`). |
79
+ | `--outDir` | `-o` | Output directory (Default: `public/swatchkit`). |
80
+ | `--force` | `-f` | Overwrite layout file during init. |
81
+
82
+ ## Configuration
83
+ Optional. Create `swatchkit.config.js` in your root for persistent settings.
84
+
85
+ ```javascript
86
+ module.exports = {
87
+ // Override default pattern directory
88
+ input: './src/patterns',
89
+
90
+ // Override default output directory
91
+ outDir: './dist/docs'
92
+ };
57
93
  ```
package/build.js CHANGED
@@ -1,132 +1,422 @@
1
1
  #!/usr/bin/env node
2
- const fs = require('fs');
3
- const path = require('path');
4
-
5
- const config = {
6
- srcDir: path.join(process.cwd(), 'src'),
7
- cssDir: path.join(process.cwd(), 'src/css'),
8
- patternsDir: path.join(process.cwd(), 'src/patterns'),
9
- layoutFile: path.join(__dirname, 'src/layout.html'),
10
- distDir: path.join(process.cwd(), 'dist'),
11
- distCssDir: path.join(process.cwd(), 'dist/css'),
12
- distJsDir: path.join(process.cwd(), 'dist/js'),
13
- outputFile: path.join(process.cwd(), 'dist/index.html'),
14
- outputJsFile: path.join(process.cwd(), 'dist/js/patterns.js')
15
- };
16
-
17
- function build() {
18
- console.log('[SwatchKit] Starting build...');
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+ const { processTokens } = require("./src/tokens");
5
+
6
+ /**
7
+ * SwatchKit Build Script
8
+ * Refactored for Phase 1 Expansion
9
+ */
10
+
11
+ // --- 1. CLI Argument Parsing ---
12
+ function parseArgs(args) {
13
+ const options = {
14
+ command: null,
15
+ watch: false,
16
+ config: null,
17
+ input: null,
18
+ outDir: null,
19
+ force: false,
20
+ };
21
+
22
+ for (let i = 2; i < args.length; i++) {
23
+ const arg = args[i];
24
+ if (arg === "init") {
25
+ options.command = "init";
26
+ } else if (arg === "-w" || arg === "--watch") {
27
+ options.watch = true;
28
+ } else if (arg === "-f" || arg === "--force") {
29
+ options.force = true;
30
+ } else if (arg === "-c" || arg === "--config") {
31
+ // Handle case where flag is last arg
32
+ if (i + 1 < args.length) {
33
+ options.config = args[++i];
34
+ }
35
+ } else if (arg === "-i" || arg === "--input") {
36
+ if (i + 1 < args.length) {
37
+ options.input = args[++i];
38
+ }
39
+ } else if (arg === "-o" || arg === "--outDir") {
40
+ if (i + 1 < args.length) {
41
+ options.outDir = args[++i];
42
+ }
43
+ }
44
+ }
45
+ return options;
46
+ }
47
+
48
+ // --- 2. Config Loading ---
49
+ function loadConfig(configPath) {
50
+ let finalPath;
51
+ if (configPath) {
52
+ finalPath = path.resolve(process.cwd(), configPath);
53
+ } else {
54
+ finalPath = path.join(process.cwd(), "swatchkit.config.js");
55
+ }
56
+
57
+ if (fs.existsSync(finalPath)) {
58
+ try {
59
+ console.log(`[SwatchKit] Loading config from ${finalPath}`);
60
+ return require(finalPath);
61
+ } catch (e) {
62
+ console.error("[SwatchKit] Error loading config file:", e.message);
63
+ return {};
64
+ }
65
+ }
66
+ return {};
67
+ }
68
+
69
+ // --- 3. Smart Defaults & Path Resolution ---
70
+ function resolveSettings(cliOptions, fileConfig) {
71
+ const cwd = process.cwd();
72
+
73
+ // Helper to find patterns dir
74
+ function findPatternsDir() {
75
+ // 1. Explicit input
76
+ if (cliOptions.input) return path.resolve(cwd, cliOptions.input);
77
+ if (fileConfig.input) return path.resolve(cwd, fileConfig.input);
78
+
79
+ // 2. Search candidates
80
+ const candidates = ["swatches", "src/swatches", "src/patterns"];
81
+ for (const cand of candidates) {
82
+ const absPath = path.join(cwd, cand);
83
+ if (fs.existsSync(absPath)) return absPath;
84
+ }
85
+
86
+ // 3. Fallback default (swatches)
87
+ return path.join(cwd, "swatches");
88
+ }
89
+
90
+ const patternsDir = findPatternsDir();
91
+
92
+ // Output Dir
93
+ // Default: public/swatchkit
94
+ const outDir = cliOptions.outDir
95
+ ? path.resolve(cwd, cliOptions.outDir)
96
+ : fileConfig.outDir
97
+ ? path.resolve(cwd, fileConfig.outDir)
98
+ : path.join(cwd, "public/swatchkit");
99
+
100
+ // CSS Dir (Legacy support: src/css)
101
+ const cssDir = path.join(cwd, "src/css");
102
+
103
+ return {
104
+ patternsDir,
105
+ outDir,
106
+ cssDir,
107
+ // Internal layout template (relative to this script)
108
+ internalLayout: path.join(__dirname, "src/layout.html"),
109
+ // Project specific layout override
110
+ projectLayout: path.join(patternsDir, "_layout.html"),
111
+
112
+ // Derived paths
113
+ distCssDir: path.join(outDir, "css"),
114
+ distTokensCssFile: path.join(outDir, "css", "tokens.css"),
115
+ distJsDir: path.join(outDir, "js"),
116
+ outputFile: path.join(outDir, "index.html"),
117
+ outputJsFile: path.join(outDir, "js/patterns.js"),
118
+ tokensCssFile: path.join(cssDir, "tokens.css"),
119
+ };
120
+ }
121
+
122
+ // --- 4. Init Command Logic ---
123
+ function runInit(settings, options) {
124
+ console.log("[SwatchKit] Initializing...");
125
+
126
+ // Ensure patterns directory exists
127
+ if (!fs.existsSync(settings.patternsDir)) {
128
+ console.log(`Creating patterns directory: ${settings.patternsDir}`);
129
+ fs.mkdirSync(settings.patternsDir, { recursive: true });
130
+ }
131
+
132
+ // Create src/tokens directory and sample colors.json
133
+ const tokensDir = path.join(process.cwd(), "src/tokens");
134
+ if (!fs.existsSync(tokensDir)) {
135
+ console.log(`Creating tokens directory: ${tokensDir}`);
136
+ fs.mkdirSync(tokensDir, { recursive: true });
137
+ }
138
+
139
+ const colorsFile = path.join(tokensDir, "colors.json");
140
+ if (!fs.existsSync(colorsFile)) {
141
+ const sampleColors = {
142
+ title: "Colors",
143
+ description:
144
+ "Hex color codes that can be shared, cross-platform. They can be converted at point of usage, such as HSL for web or CMYK for print.",
145
+ items: [
146
+ { name: "Dark", value: "#171406" },
147
+ { name: "Dark Glare", value: "#2d2816" },
148
+ { name: "Mid", value: "#ABA9A2" },
149
+ { name: "Light", value: "#ffffff" },
150
+ { name: "Primary", value: "#fcad26" },
151
+ ],
152
+ };
153
+ fs.writeFileSync(colorsFile, JSON.stringify(sampleColors, null, 2));
154
+ console.log(`Created sample tokens file at ${colorsFile}`);
155
+ }
156
+
157
+ // Create sample colors.html pattern
158
+ const colorsPatternFile = path.join(settings.patternsDir, "colors.html");
159
+ if (!fs.existsSync(colorsPatternFile)) {
160
+ const colorsHtml = `
161
+ <style>
162
+ .swatch-grid {
163
+ display: grid;
164
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
165
+ gap: 1rem;
166
+ padding: 1rem;
167
+ }
168
+ .swatch {
169
+ border: 1px solid #ddd;
170
+ border-radius: 8px;
171
+ overflow: hidden;
172
+ }
173
+ .swatch-color {
174
+ height: 100px;
175
+ width: 100%;
176
+ }
177
+ .swatch-info {
178
+ padding: 0.5rem;
179
+ font-family: monospace;
180
+ font-size: 0.9rem;
181
+ background: #f9f9f9;
182
+ }
183
+ </style>
184
+
185
+ <div class="swatch-grid">
186
+ <div class="swatch">
187
+ <div class="swatch-color" style="background-color: var(--color-dark);"></div>
188
+ <div class="swatch-info">
189
+ <strong>Dark</strong><br>
190
+ var(--color-dark)
191
+ </div>
192
+ </div>
193
+ <div class="swatch">
194
+ <div class="swatch-color" style="background-color: var(--color-dark-glare);"></div>
195
+ <div class="swatch-info">
196
+ <strong>Dark Glare</strong><br>
197
+ var(--color-dark-glare)
198
+ </div>
199
+ </div>
200
+ <div class="swatch">
201
+ <div class="swatch-color" style="background-color: var(--color-mid);"></div>
202
+ <div class="swatch-info">
203
+ <strong>Mid</strong><br>
204
+ var(--color-mid)
205
+ </div>
206
+ </div>
207
+ <div class="swatch">
208
+ <div class="swatch-color" style="background-color: var(--color-light);"></div>
209
+ <div class="swatch-info">
210
+ <strong>Light</strong><br>
211
+ var(--color-light)
212
+ </div>
213
+ </div>
214
+ <div class="swatch">
215
+ <div class="swatch-color" style="background-color: var(--color-primary);"></div>
216
+ <div class="swatch-info">
217
+ <strong>Primary</strong><br>
218
+ var(--color-primary)
219
+ </div>
220
+ </div>
221
+ </div>
222
+ `;
223
+ fs.writeFileSync(colorsPatternFile, colorsHtml.trim());
224
+ console.log(`Created sample pattern at ${colorsPatternFile}`);
225
+ }
226
+
227
+ // Generate initial CSS
228
+ processTokens(process.cwd(), settings.cssDir);
229
+
230
+ const targetLayout = settings.projectLayout;
231
+
232
+ if (fs.existsSync(targetLayout) && !options.force) {
233
+ console.warn(`Warning: Layout file already exists at ${targetLayout}`);
234
+ console.warn("Use --force to overwrite.");
235
+ return;
236
+ }
237
+
238
+ if (fs.existsSync(settings.internalLayout)) {
239
+ const layoutContent = fs.readFileSync(settings.internalLayout, "utf-8");
240
+ fs.writeFileSync(targetLayout, layoutContent);
241
+ console.log(`Created layout file at ${targetLayout}`);
242
+ } else {
243
+ console.error(
244
+ `Error: Internal layout file not found at ${settings.internalLayout}`,
245
+ );
246
+ process.exit(1);
247
+ }
248
+ }
249
+
250
+ // --- 5. Build Logic ---
251
+ function build(settings) {
252
+ console.log(`[SwatchKit] Starting build...`);
253
+ console.log(` Patterns: ${settings.patternsDir}`);
254
+ console.log(` Output: ${settings.outDir}`);
19
255
 
20
256
  // 1. Check if patterns directory exists
21
- if (!fs.existsSync(config.patternsDir)) {
22
- console.error('Error: No patterns found. Create src/patterns to get started.');
257
+ if (!fs.existsSync(settings.patternsDir)) {
258
+ console.error(
259
+ `Error: Patterns directory not found at ${settings.patternsDir}`,
260
+ );
261
+ console.error('Run "swatchkit init" to get started.');
23
262
  process.exit(1);
24
263
  }
25
264
 
26
265
  // 2. Ensure dist directories exist
27
- [config.distDir, config.distCssDir, config.distJsDir].forEach(dir => {
266
+ [settings.outDir, settings.distCssDir, settings.distJsDir].forEach((dir) => {
28
267
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
29
268
  });
30
269
 
270
+ // 2.5 Process Tokens
271
+ processTokens(process.cwd(), settings.cssDir);
272
+
31
273
  // 3. Copy CSS files
32
- console.log('Copying CSS...');
33
- if (fs.existsSync(config.cssDir)) {
34
- const cssFiles = fs.readdirSync(config.cssDir).filter(file => file.endsWith('.css'));
35
- cssFiles.forEach(file => {
36
- fs.copyFileSync(path.join(config.cssDir, file), path.join(config.distCssDir, file));
37
- });
274
+ if (fs.existsSync(settings.cssDir)) {
275
+ console.log("Copying CSS...");
276
+ const cssFiles = fs
277
+ .readdirSync(settings.cssDir)
278
+ .filter((file) => file.endsWith(".css"));
279
+ cssFiles.forEach((file) => {
280
+ fs.copyFileSync(
281
+ path.join(settings.cssDir, file),
282
+ path.join(settings.distCssDir, file),
283
+ );
284
+ });
38
285
  }
39
286
 
40
287
  // 4. Read patterns & JS
41
- console.log('Processing patterns...');
288
+ console.log("Processing patterns...");
42
289
  const patterns = [];
43
290
  const scripts = [];
44
291
 
45
- const items = fs.readdirSync(config.patternsDir);
46
-
47
- items.forEach(item => {
48
- const itemPath = path.join(config.patternsDir, item);
49
- const stat = fs.statSync(itemPath);
50
-
51
- let name, content, id;
52
-
53
- // Handle Directory Pattern (Folder with index.html + optional JS files)
54
- if (stat.isDirectory()) {
55
- const indexFile = path.join(itemPath, 'index.html');
56
-
57
- if (fs.existsSync(indexFile)) {
58
- name = item;
59
- id = item;
60
- content = fs.readFileSync(indexFile, 'utf-8');
61
-
62
- // Find all .js files in this directory
63
- const jsFiles = fs.readdirSync(itemPath).filter(file => file.endsWith('.js'));
64
-
65
- jsFiles.forEach(jsFile => {
66
- const scriptContent = fs.readFileSync(path.join(itemPath, jsFile), 'utf-8');
67
- scripts.push(`
292
+ const items = fs.readdirSync(settings.patternsDir);
293
+
294
+ items.forEach((item) => {
295
+ // Skip _layout.html or hidden files
296
+ if (item.startsWith("_") || item.startsWith(".")) return;
297
+
298
+ const itemPath = path.join(settings.patternsDir, item);
299
+ const stat = fs.statSync(itemPath);
300
+
301
+ let name, content, id;
302
+
303
+ // Handle Directory Pattern
304
+ if (stat.isDirectory()) {
305
+ const indexFile = path.join(itemPath, "index.html");
306
+
307
+ if (fs.existsSync(indexFile)) {
308
+ name = item;
309
+ id = item;
310
+ content = fs.readFileSync(indexFile, "utf-8");
311
+
312
+ // Find all .js files
313
+ const jsFiles = fs
314
+ .readdirSync(itemPath)
315
+ .filter((file) => file.endsWith(".js"));
316
+
317
+ jsFiles.forEach((jsFile) => {
318
+ const scriptContent = fs.readFileSync(
319
+ path.join(itemPath, jsFile),
320
+ "utf-8",
321
+ );
322
+ scripts.push(`
68
323
  /* --- Pattern: ${name} / File: ${jsFile} --- */
69
324
  (function() {
70
325
  ${scriptContent}
71
326
  })();
72
327
  `);
73
- });
74
- }
75
- }
76
- // Handle Single File Pattern (.html)
77
- else if (item.endsWith('.html')) {
78
- name = path.basename(item, '.html');
79
- id = name;
80
- content = fs.readFileSync(itemPath, 'utf-8');
328
+ });
81
329
  }
330
+ }
331
+ // Handle Single File Pattern
332
+ else if (item.endsWith(".html")) {
333
+ name = path.basename(item, ".html");
334
+ id = name;
335
+ content = fs.readFileSync(itemPath, "utf-8");
336
+ }
82
337
 
83
- if (name && content) {
84
- patterns.push({ name, id, content });
85
- }
86
- });
338
+ if (name && content) {
339
+ patterns.push({ name, id, content });
340
+ }
341
+ });
87
342
 
88
343
  // 5. Generate HTML fragments
89
- const sidebarLinks = patterns.map(p =>
90
- `<a href="#${p.id}">${p.name}</a>`
91
- ).join('\n');
92
-
93
- const patternBlocks = patterns.map(p => {
94
- const escapedContent = p.content
95
- .replace(/&/g, "&amp;")
96
- .replace(/</g, "&lt;")
97
- .replace(/>/g, "&gt;")
98
- .replace(/"/g, "&quot;")
99
- .replace(/'/g, "&#039;");
100
-
101
- return `
344
+ const sidebarLinks = patterns
345
+ .map((p) => `<a href="#${p.id}">${p.name}</a>`)
346
+ .join("\n");
347
+
348
+ const patternBlocks = patterns
349
+ .map((p) => {
350
+ const escapedContent = p.content
351
+ .replace(/&/g, "&amp;")
352
+ .replace(/</g, "&lt;")
353
+ .replace(/>/g, "&gt;")
354
+ .replace(/"/g, "&quot;")
355
+ .replace(/'/g, "&#039;");
356
+
357
+ return `
102
358
  <section id="${p.id}">
103
359
  <h2>${p.name}</h2>
104
360
  <div class="preview">${p.content}</div>
105
361
  <pre><code>${escapedContent}</code></pre>
106
362
  </section>
107
363
  `;
108
- }).join('\n');
364
+ })
365
+ .join("\n");
109
366
 
110
367
  // 6. Write JS Bundle
111
368
  if (scripts.length > 0) {
112
- fs.writeFileSync(config.outputJsFile, scripts.join('\n'));
113
- console.log(`Bundled ${scripts.length} scripts to ${config.outputJsFile}`);
369
+ fs.writeFileSync(settings.outputJsFile, scripts.join("\n"));
370
+ console.log(
371
+ `Bundled ${scripts.length} scripts to ${settings.outputJsFile}`,
372
+ );
373
+ } else {
374
+ fs.writeFileSync(settings.outputJsFile, "// No pattern scripts found");
375
+ }
376
+
377
+ // 7. Load Layout
378
+ let layoutContent;
379
+ if (fs.existsSync(settings.projectLayout)) {
380
+ console.log(`Using custom layout: ${settings.projectLayout}`);
381
+ layoutContent = fs.readFileSync(settings.projectLayout, "utf-8");
114
382
  } else {
115
- // Write empty file if no scripts so browser doesn't 404
116
- fs.writeFileSync(config.outputJsFile, '// No pattern scripts found');
383
+ // console.log(`Using internal layout`);
384
+ layoutContent = fs.readFileSync(settings.internalLayout, "utf-8");
385
+ }
386
+
387
+ let headExtras = "";
388
+ // Check if the tokens file exists in the *output* directory (where we copied it to)
389
+ if (fs.existsSync(settings.distTokensCssFile)) {
390
+ headExtras = '<link rel="stylesheet" href="css/tokens.css">';
117
391
  }
118
392
 
119
- // 7. Read layout and replace placeholders
120
- let layout = fs.readFileSync(config.layoutFile, 'utf-8');
121
-
122
- const finalHtml = layout
123
- .replace('<!-- SIDEBAR_LINKS -->', sidebarLinks)
124
- .replace('<!-- PATTERNS -->', patternBlocks);
393
+ const finalHtml = layoutContent
394
+ .replace("<!-- SIDEBAR_LINKS -->", sidebarLinks)
395
+ .replace("<!-- PATTERNS -->", patternBlocks)
396
+ .replace("<!-- HEAD_EXTRAS -->", headExtras);
125
397
 
126
398
  // 8. Write output
127
- fs.writeFileSync(config.outputFile, finalHtml);
128
-
129
- console.log(`Build complete! Generated ${config.outputFile}`);
399
+ fs.writeFileSync(settings.outputFile, finalHtml);
400
+
401
+ console.log(`Build complete! Generated ${settings.outputFile}`);
402
+ }
403
+
404
+ // --- Main Execution ---
405
+ try {
406
+ const cliOptions = parseArgs(process.argv);
407
+ const fileConfig = loadConfig(cliOptions.config);
408
+ const settings = resolveSettings(cliOptions, fileConfig);
409
+
410
+ if (cliOptions.command === "init") {
411
+ runInit(settings, cliOptions);
412
+ } else {
413
+ build(settings);
414
+ if (cliOptions.watch) {
415
+ console.log("[SwatchKit] Watch mode is not yet fully implemented.");
416
+ }
417
+ }
418
+ } catch (error) {
419
+ console.error("[SwatchKit] Error:", error.message);
420
+ process.exit(1);
130
421
  }
131
422
 
132
- build();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swatchkit",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A lightweight tool for creating HTML pattern libraries.",
5
5
  "main": "build.js",
6
6
  "bin": {
package/src/layout.html CHANGED
@@ -5,6 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>SwatchKit</title>
7
7
  <link rel="stylesheet" href="/css/global.css" />
8
+ <!-- HEAD_EXTRAS -->
8
9
  <style>
9
10
  body {
10
11
  display: flex;
@@ -86,4 +87,4 @@
86
87
  </main>
87
88
  <script src="js/patterns.js"></script>
88
89
  </body>
89
- </html>
90
+ </html>