@matchkit.io/cli 0.1.1 → 0.1.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.
@@ -1,9 +1,111 @@
1
1
  import * as p from "@clack/prompts";
2
2
  import pc from "picocolors";
3
- import { writeFileSync, mkdirSync, existsSync } from "node:fs";
3
+ import { writeFileSync, mkdirSync, existsSync, readFileSync } from "node:fs";
4
4
  import { join, dirname } from "node:path";
5
5
  import { readConfig, configExists, writeConfig, createDefaultConfig } from "../utils/config.js";
6
6
  import { getApiKey, authFetch, API_BASE_URL } from "../utils/auth.js";
7
+ // Marker used to detect MatchKit-managed AI rules files
8
+ const MATCHKIT_MARKER = "<!-- managed:matchkit -->";
9
+ /**
10
+ * Build the content for AI rules files.
11
+ * This is the mandatory instruction set that tells AI tools to use the design system.
12
+ */
13
+ function buildAiRulesContent(skillDir, theme) {
14
+ return `${MATCHKIT_MARKER}
15
+ # MatchKit Design System — ${theme}-ui
16
+
17
+ > Auto-generated by \`matchkit pull\`. Do not edit the marker line above.
18
+
19
+ ## MANDATORY — This project uses a complete design system
20
+
21
+ A full design system is installed at \`${skillDir}/\`. You MUST use it for ALL UI work.
22
+
23
+ ### Before writing ANY UI code:
24
+
25
+ 1. **Read \`${skillDir}/SKILL.md\`** — contains design rules, component specs, and setup instructions
26
+ 2. **Read \`${skillDir}/registry.json\`** — lists all 27 available components with their dependencies
27
+ 3. **Copy \`${skillDir}/globals.css\`** to \`src/styles/globals.css\` if it doesn't exist yet
28
+ 4. **Create \`src/lib/utils.ts\`** with the \`cn()\` helper if it doesn't exist yet:
29
+ \`\`\`ts
30
+ import { clsx, type ClassValue } from "clsx";
31
+ import { twMerge } from "tailwind-merge";
32
+ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }
33
+ \`\`\`
34
+ 5. **Copy component files** from \`${skillDir}/components/\` to \`src/components/ui/\` as needed
35
+
36
+ ### Rules — follow these at ALL times:
37
+
38
+ - **ALWAYS** check \`${skillDir}/registry.json\` before creating any component — if it exists there, use it
39
+ - **NEVER** create your own \`globals.css\`, Tailwind theme, or color tokens — use the provided \`globals.css\`
40
+ - **NEVER** hardcode hex colors, pixel spacing, or font sizes — use CSS variables from \`globals.css\`
41
+ - **NEVER** improvise a component if one already exists in the registry
42
+ - **NEVER** modify files inside \`${skillDir}/\` — it is the upstream source of truth
43
+ - **ALWAYS** use \`@/components/ui/{name}\` import paths for design system components
44
+ - **ALWAYS** use \`@/lib/utils\` for the \`cn()\` helper
45
+
46
+ ### Available resources in \`${skillDir}/\`:
47
+
48
+ | Path | Contents |
49
+ |------|----------|
50
+ | \`SKILL.md\` | Design rules, philosophy, component specs |
51
+ | \`registry.json\` | Component registry with types, layers, dependencies |
52
+ | \`components/*.tsx\` | 27 production-ready components |
53
+ | \`layouts/*.tsx\` | 6 page layout references |
54
+ | \`globals.css\` | Complete Tailwind v4 CSS with all tokens |
55
+ | \`tokens/*.json\` | Design token values |
56
+ | \`patterns/*.md\` | Responsive, dark mode, a11y, composition patterns |
57
+ `;
58
+ }
59
+ /**
60
+ * Build Cursor .mdc format content (has YAML frontmatter with alwaysApply).
61
+ */
62
+ function buildCursorMdcContent(skillDir, theme) {
63
+ return `---
64
+ description: MatchKit ${theme}-ui design system — mandatory rules for all UI work
65
+ alwaysApply: true
66
+ ---
67
+ ${buildAiRulesContent(skillDir, theme)}`;
68
+ }
69
+ /**
70
+ * Write AI rules files to the project root.
71
+ * Only writes if the file doesn't exist or is MatchKit-managed (has the marker).
72
+ * Returns the list of files that were written.
73
+ */
74
+ function writeAiRulesFiles(cwd, skillDir, theme) {
75
+ const content = buildAiRulesContent(skillDir, theme);
76
+ const cursorMdcContent = buildCursorMdcContent(skillDir, theme);
77
+ const written = [];
78
+ const targets = [
79
+ { path: "CLAUDE.md", label: "CLAUDE.md", content },
80
+ { path: ".cursorrules", label: ".cursorrules", content },
81
+ { path: ".cursor/rules/matchkit.mdc", label: ".cursor/rules/matchkit.mdc", content: cursorMdcContent },
82
+ { path: ".github/copilot-instructions.md", label: ".github/copilot-instructions.md", content },
83
+ { path: ".windsurfrules", label: ".windsurfrules", content },
84
+ ];
85
+ for (const target of targets) {
86
+ const fullPath = join(cwd, target.path);
87
+ let shouldWrite = false;
88
+ if (!existsSync(fullPath)) {
89
+ shouldWrite = true;
90
+ }
91
+ else {
92
+ // File exists — only overwrite if it's MatchKit-managed
93
+ const existing = readFileSync(fullPath, "utf-8");
94
+ if (existing.includes(MATCHKIT_MARKER)) {
95
+ shouldWrite = true;
96
+ }
97
+ }
98
+ if (shouldWrite) {
99
+ const dir = dirname(fullPath);
100
+ if (!existsSync(dir)) {
101
+ mkdirSync(dir, { recursive: true });
102
+ }
103
+ writeFileSync(fullPath, target.content);
104
+ written.push(target.label);
105
+ }
106
+ }
107
+ return written;
108
+ }
7
109
  export async function pullCommand(options) {
8
110
  p.intro(pc.bold("matchkit pull"));
9
111
  // Check auth
@@ -131,6 +233,11 @@ export async function pullCommand(options) {
131
233
  s.stop(`Extracted ${fileCount} files`);
132
234
  p.log.success(`${pc.bold(theme + "-ui")} v${version} → ${pc.dim(skillDir)}`);
133
235
  p.log.info(`Build: ${pc.dim(buildId)}`);
236
+ // Generate AI rules files so every AI tool uses the design system
237
+ const writtenRules = writeAiRulesFiles(process.cwd(), skillDir, theme);
238
+ if (writtenRules.length > 0) {
239
+ p.log.success(`AI rules → ${writtenRules.map((f) => pc.dim(f)).join(", ")}`);
240
+ }
134
241
  p.outro("Design system is up to date.");
135
242
  }
136
243
  catch (err) {
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ const program = new Command();
11
11
  program
12
12
  .name("matchkit")
13
13
  .description("MatchKit — style-agnostic design system CLI")
14
- .version("0.1.1");
14
+ .version("0.1.2");
15
15
  program
16
16
  .command("init")
17
17
  .description("Initialize a MatchKit design system in your project")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matchkit.io/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "CLI for MatchKit design system skills. Init projects, add components, manage your design system.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",