oh-my-design-cli 0.1.3 → 1.0.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 (74) hide show
  1. package/.claude/hooks/post-edit-watch.cjs +99 -0
  2. package/.claude/hooks/session-end-foldin.cjs +96 -0
  3. package/.claude/hooks/session-state-loader.cjs +64 -0
  4. package/.claude/hooks/skill-activation.cjs +73 -0
  5. package/.claude/settings.json +55 -0
  6. package/.claude/skills/skill-rules.json +87 -0
  7. package/AGENTS.md +111 -0
  8. package/README.md +75 -202
  9. package/agents/AGENT.md +53 -0
  10. package/agents/omd-3d-blender.md +269 -0
  11. package/agents/omd-a11y-auditor.md +97 -0
  12. package/agents/omd-asset-curator.md +260 -0
  13. package/agents/omd-critic.md +181 -0
  14. package/agents/omd-master.md +548 -0
  15. package/agents/omd-microcopy.md +63 -0
  16. package/agents/omd-persona-tester.md +118 -0
  17. package/agents/omd-ui-junior.md +129 -0
  18. package/agents/omd-ux-engineer.md +265 -0
  19. package/agents/omd-ux-researcher.md +62 -0
  20. package/agents/omd-ux-writer.md +181 -0
  21. package/data/opt-out-corpus.json +141 -0
  22. package/data/reference-fingerprints.json +1495 -0
  23. package/dist/bin/oh-my-design.js +3 -818
  24. package/dist/bin/oh-my-design.js.map +1 -1
  25. package/dist/install-skills-SVIYKXOE.js +442 -0
  26. package/dist/install-skills-SVIYKXOE.js.map +1 -0
  27. package/package.json +23 -21
  28. package/scripts/context.cjs +91 -0
  29. package/scripts/postinstall.cjs +54 -0
  30. package/skills/omd-apply/SKILL.md +64 -53
  31. package/skills/omd-harness/SKILL.md +271 -0
  32. package/skills/omd-learn/SKILL.md +55 -35
  33. package/skills/omd-remember/SKILL.md +93 -15
  34. package/skills/omd-sync/SKILL.md +140 -16
  35. package/dist/chunk-6YNSV3VY.js +0 -35
  36. package/dist/chunk-6YNSV3VY.js.map +0 -1
  37. package/dist/chunk-MHFYGZSO.js +0 -337
  38. package/dist/chunk-MHFYGZSO.js.map +0 -1
  39. package/dist/chunk-N2JG6N4Q.js +0 -264
  40. package/dist/chunk-N2JG6N4Q.js.map +0 -1
  41. package/dist/chunk-OOQQEUGX.js +0 -46
  42. package/dist/chunk-OOQQEUGX.js.map +0 -1
  43. package/dist/chunk-OR5DHENY.js +0 -250
  44. package/dist/chunk-OR5DHENY.js.map +0 -1
  45. package/dist/customizer-CM76752R.js +0 -8
  46. package/dist/customizer-CM76752R.js.map +0 -1
  47. package/dist/index.d.ts +0 -559
  48. package/dist/index.js +0 -3113
  49. package/dist/index.js.map +0 -1
  50. package/dist/init-UMM4XIV5.js +0 -675
  51. package/dist/init-UMM4XIV5.js.map +0 -1
  52. package/dist/install-skills-CM6VXFZJ.js +0 -152
  53. package/dist/install-skills-CM6VXFZJ.js.map +0 -1
  54. package/dist/learn-33LHKEJA.js +0 -140
  55. package/dist/learn-33LHKEJA.js.map +0 -1
  56. package/dist/reference-YMNAOXJQ.js +0 -47
  57. package/dist/reference-YMNAOXJQ.js.map +0 -1
  58. package/dist/reference-parser-TM3CJPNE.js +0 -10
  59. package/dist/reference-parser-TM3CJPNE.js.map +0 -1
  60. package/dist/remember-UAFA5B2O.js +0 -78
  61. package/dist/remember-UAFA5B2O.js.map +0 -1
  62. package/dist/sync-FDYRKNFE.js +0 -417
  63. package/dist/sync-FDYRKNFE.js.map +0 -1
  64. package/dist/templates/templates/design-md.hbs +0 -44
  65. package/dist/templates/templates/partials/agent-prompt-guide.hbs +0 -28
  66. package/dist/templates/templates/partials/color-palette.hbs +0 -49
  67. package/dist/templates/templates/partials/component-stylings.hbs +0 -28
  68. package/dist/templates/templates/partials/depth-elevation.hbs +0 -31
  69. package/dist/templates/templates/partials/dos-donts.hbs +0 -13
  70. package/dist/templates/templates/partials/layout.hbs +0 -30
  71. package/dist/templates/templates/partials/responsive.hbs +0 -25
  72. package/dist/templates/templates/partials/shadcn-tokens.hbs +0 -64
  73. package/dist/templates/templates/partials/typography.hbs +0 -43
  74. package/dist/templates/templates/partials/visual-theme.hbs +0 -26
@@ -1,264 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/core/reference-parser.ts
4
- import { readFileSync, readdirSync, existsSync } from "fs";
5
- import { join, dirname } from "path";
6
- import { fileURLToPath } from "url";
7
- var __dirname = dirname(fileURLToPath(import.meta.url));
8
- var CATEGORIES = {
9
- stripe: "Fintech",
10
- coinbase: "Fintech",
11
- revolut: "Fintech",
12
- wise: "Fintech",
13
- kraken: "Fintech",
14
- vercel: "Developer Tools",
15
- cursor: "Developer Tools",
16
- warp: "Developer Tools",
17
- expo: "Developer Tools",
18
- lovable: "Developer Tools",
19
- raycast: "Developer Tools",
20
- superhuman: "Developer Tools",
21
- supabase: "Backend & DevOps",
22
- mongodb: "Backend & DevOps",
23
- sentry: "Backend & DevOps",
24
- posthog: "Backend & DevOps",
25
- hashicorp: "Backend & DevOps",
26
- clickhouse: "Backend & DevOps",
27
- composio: "Backend & DevOps",
28
- sanity: "Backend & DevOps",
29
- notion: "Productivity",
30
- "linear.app": "Productivity",
31
- "cal": "Productivity",
32
- zapier: "Productivity",
33
- intercom: "Productivity",
34
- resend: "Productivity",
35
- mintlify: "Productivity",
36
- figma: "Design Tools",
37
- framer: "Design Tools",
38
- miro: "Design Tools",
39
- webflow: "Design Tools",
40
- airtable: "Design Tools",
41
- clay: "Design Tools",
42
- claude: "AI & LLM",
43
- cohere: "AI & LLM",
44
- mistral: "AI & LLM",
45
- "mistral.ai": "AI & LLM",
46
- ollama: "AI & LLM",
47
- "opencode.ai": "AI & LLM",
48
- replicate: "AI & LLM",
49
- "together.ai": "AI & LLM",
50
- "x.ai": "AI & LLM",
51
- elevenlabs: "AI & LLM",
52
- minimax: "AI & LLM",
53
- runwayml: "AI & LLM",
54
- voltagent: "AI & LLM",
55
- apple: "Consumer Tech",
56
- spotify: "Consumer Tech",
57
- uber: "Consumer Tech",
58
- airbnb: "Consumer Tech",
59
- pinterest: "Consumer Tech",
60
- nvidia: "Consumer Tech",
61
- ibm: "Consumer Tech",
62
- spacex: "Consumer Tech",
63
- shopify: "E-commerce",
64
- semrush: "Marketing",
65
- tesla: "Automotive",
66
- bmw: "Automotive",
67
- ferrari: "Automotive",
68
- lamborghini: "Automotive",
69
- renault: "Automotive",
70
- bugatti: "Automotive",
71
- karrot: "Korean Tech",
72
- toss: "Korean Tech",
73
- baemin: "Korean Tech",
74
- kakao: "Korean Tech"
75
- };
76
- var CATEGORY_ORDER = [
77
- "Korean Tech",
78
- "AI & LLM",
79
- "Design Tools",
80
- "Developer Tools",
81
- "Productivity",
82
- "Consumer Tech",
83
- "Fintech",
84
- "Backend & DevOps",
85
- "E-commerce",
86
- "Automotive",
87
- "Marketing"
88
- ];
89
- function extractHexColors(text) {
90
- const matches = text.match(/#[0-9a-fA-F]{6}\b/g) || [];
91
- return [...new Set(matches)];
92
- }
93
- function extractPrimaryColor(md) {
94
- const section2Match = md.match(/## 2\. Color Palette.*?\n([\s\S]*?)(?=## 3\.)/);
95
- if (section2Match) {
96
- const section2 = section2Match[1];
97
- const primaryMatch = section2.match(/\*\*([^*]+)\*\*\s*\(`(#[0-9a-fA-F]{6})`\).*?(?:primary|brand|CTA|main)/i);
98
- if (primaryMatch) {
99
- return { hex: primaryMatch[2], name: primaryMatch[1] };
100
- }
101
- const firstHex = section2.match(/`(#[0-9a-fA-F]{6})`/);
102
- if (firstHex) {
103
- return { hex: firstHex[1], name: "Primary" };
104
- }
105
- }
106
- const allHex = extractHexColors(md);
107
- return { hex: allHex[0] || "#6366f1", name: "Primary" };
108
- }
109
- function extractBackground(md) {
110
- const patterns = [
111
- /(?:page|canvas|marketing)\s+background.*?`(#[0-9a-fA-F]{6})`/i,
112
- /(?:Pure White|White).*?`(#[0-9a-fA-F]{6})`.*?(?:page background|background)/i,
113
- /Background:.*?Pure White.*?\(`(#[0-9a-fA-F]{6})`\)/i,
114
- /(?:Page|Site)\s+background.*?`(#[0-9a-fA-F]{6})`/i,
115
- // Match "hex: The primary page background" pattern (hex before description)
116
- /`(#[0-9a-fA-F]{6})`[^.]*?(?:primary\s+)?page\s+background/i
117
- ];
118
- for (const pattern of patterns) {
119
- const match = md.match(pattern);
120
- if (match) return match[1];
121
- }
122
- const section2 = md.match(/## 2\. Color.*?\n([\s\S]*?)(?=## 3\.)/);
123
- if (section2) {
124
- const surfaceBg = section2[1].match(/(?:Pure White|Pure Black|page background|Background\b).*?`(#[0-9a-fA-F]{6})`/i);
125
- if (surfaceBg) return surfaceBg[1];
126
- }
127
- const quickRef = md.match(/Quick Color Reference[\s\S]*?(?:Page\s+)?Background.*?[(`](#[0-9a-fA-F]{6})[)`]/i);
128
- if (quickRef) return quickRef[1];
129
- if (md.match(/dark.mode.(?:native|first)/i)) {
130
- const darkBg = md.match(/(?:marketing|deepest|canvas).*?`(#[0-9a-fA-F]{6})`/i);
131
- if (darkBg) return darkBg[1];
132
- }
133
- return "#ffffff";
134
- }
135
- function extractForeground(md) {
136
- const fgMatch = md.match(/(?:heading|primary text).*?`(#[0-9a-fA-F]{6})`/i);
137
- return fgMatch ? fgMatch[1] : "#09090b";
138
- }
139
- function extractAccent(md) {
140
- const accentMatch = md.match(/(?:accent|secondary).*?`(#[0-9a-fA-F]{6})`/i);
141
- return accentMatch ? accentMatch[1] : void 0;
142
- }
143
- function extractBorder(md) {
144
- const borderMatch = md.match(/(?:border.*?default|border.*?standard).*?`(#[0-9a-fA-F]{6})`/i);
145
- return borderMatch ? borderMatch[1] : void 0;
146
- }
147
- function extractTypography(md) {
148
- const section3 = md.match(/## 3\. Typography.*?\n([\s\S]*?)(?=## 4\.)/);
149
- let primary = "Inter";
150
- let mono;
151
- let headingWeight = "600";
152
- if (section3) {
153
- const text = section3[1];
154
- const primaryMatch = text.match(/\*\*Primary\*\*:\s*`([^`]+)`/i);
155
- if (primaryMatch) primary = primaryMatch[1].split(",")[0].trim();
156
- const monoMatch = text.match(/\*\*Monospace\*\*:\s*`([^`]+)`/i);
157
- if (monoMatch) mono = monoMatch[1].split(",")[0].trim();
158
- const weightMatch = text.match(/Display.*?\|\s*(\d{3})\s*\|/);
159
- if (weightMatch) headingWeight = weightMatch[1];
160
- }
161
- return { primary, mono, headingWeight };
162
- }
163
- function extractRadius(md) {
164
- const radiusMatch = md.match(/(?:border-radius|radius).*?(\d+px(?:\s*[-–]\s*\d+px)?)/i);
165
- return radiusMatch ? radiusMatch[1] : "6px";
166
- }
167
- function extractMood(md) {
168
- const section1 = md.match(/## 1\. Visual Theme.*?\n([\s\S]*?)(?=## 2\.)/);
169
- if (!section1) return "";
170
- const text = section1[1].trim();
171
- const firstParagraph = text.split("\n\n")[0];
172
- return firstParagraph.slice(0, 300);
173
- }
174
- function toDisplayName(id) {
175
- const special = {
176
- "linear.app": "Linear",
177
- "cal": "Cal.com",
178
- "mistral.ai": "Mistral AI",
179
- "opencode.ai": "OpenCode AI",
180
- "together.ai": "Together AI",
181
- "x.ai": "xAI",
182
- ibm: "IBM",
183
- bmw: "BMW",
184
- nvidia: "NVIDIA",
185
- posthog: "PostHog",
186
- supabase: "Supabase",
187
- voltagent: "VoltAgent",
188
- elevenlabs: "ElevenLabs",
189
- runwayml: "RunwayML",
190
- spacex: "SpaceX",
191
- coinbase: "Coinbase",
192
- airbnb: "Airbnb",
193
- clickhouse: "ClickHouse",
194
- karrot: "Karrot",
195
- toss: "Toss",
196
- baemin: "Baemin",
197
- kakao: "Kakao"
198
- };
199
- return special[id] || id.charAt(0).toUpperCase() + id.slice(1);
200
- }
201
- function getReferencesDir() {
202
- const candidates = [
203
- join(process.cwd(), "references"),
204
- join(__dirname, "..", "..", "references"),
205
- join(__dirname, "..", "references")
206
- ];
207
- for (const dir of candidates) {
208
- if (existsSync(dir)) return dir;
209
- }
210
- throw new Error("references/ directory not found. Searched: " + candidates.join(", "));
211
- }
212
- function loadReference(id) {
213
- const dir = getReferencesDir();
214
- const mdPath = join(dir, id, "DESIGN.md");
215
- if (!existsSync(mdPath)) {
216
- throw new Error(`Reference not found: ${id}`);
217
- }
218
- const designMd = readFileSync(mdPath, "utf-8");
219
- const primary = extractPrimaryColor(designMd);
220
- return {
221
- id,
222
- name: toDisplayName(id),
223
- category: CATEGORIES[id] || "Other",
224
- designMd,
225
- colors: {
226
- primary: primary.hex,
227
- primaryName: primary.name,
228
- background: extractBackground(designMd),
229
- foreground: extractForeground(designMd),
230
- accent: extractAccent(designMd),
231
- border: extractBorder(designMd)
232
- },
233
- typography: extractTypography(designMd),
234
- radius: extractRadius(designMd),
235
- mood: extractMood(designMd)
236
- };
237
- }
238
- function listReferences() {
239
- const dir = getReferencesDir();
240
- const entries = readdirSync(dir, { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync(join(dir, d.name, "DESIGN.md"))).map((d) => {
241
- const mdPath = join(dir, d.name, "DESIGN.md");
242
- const md = readFileSync(mdPath, "utf-8");
243
- const primary = extractPrimaryColor(md);
244
- return {
245
- id: d.name,
246
- name: toDisplayName(d.name),
247
- category: CATEGORIES[d.name] || "Other",
248
- primaryColor: primary.hex
249
- };
250
- });
251
- return entries.sort((a, b) => {
252
- const ai = CATEGORY_ORDER.indexOf(a.category);
253
- const bi = CATEGORY_ORDER.indexOf(b.category);
254
- const oa = ai === -1 ? 999 : ai;
255
- const ob = bi === -1 ? 999 : bi;
256
- return oa - ob || a.name.localeCompare(b.name);
257
- });
258
- }
259
-
260
- export {
261
- loadReference,
262
- listReferences
263
- };
264
- //# sourceMappingURL=chunk-N2JG6N4Q.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/reference-parser.ts"],"sourcesContent":["import { readFileSync, readdirSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface ReferenceEntry {\n id: string; // folder name e.g. \"stripe\"\n name: string; // display name e.g. \"Stripe\"\n category: string; // e.g. \"Fintech\"\n designMd: string; // full DESIGN.md content\n colors: ExtractedColors;\n typography: ExtractedTypography;\n radius: string; // e.g. \"4px-8px\"\n mood: string; // extracted from section 1\n}\n\nexport interface ExtractedColors {\n primary: string; // main brand hex\n primaryName: string; // e.g. \"Stripe Purple\"\n background: string;\n foreground: string;\n accent?: string;\n border?: string;\n}\n\nexport interface ExtractedTypography {\n primary: string; // e.g. \"sohne-var\"\n mono?: string; // e.g. \"SourceCodePro\"\n headingWeight: string;\n}\n\n// ── Category mapping ─────────────────────────────────────────────\n\nconst CATEGORIES: Record<string, string> = {\n stripe: 'Fintech', coinbase: 'Fintech', revolut: 'Fintech', wise: 'Fintech', kraken: 'Fintech',\n vercel: 'Developer Tools', cursor: 'Developer Tools', warp: 'Developer Tools',\n expo: 'Developer Tools', lovable: 'Developer Tools', raycast: 'Developer Tools', superhuman: 'Developer Tools',\n supabase: 'Backend & DevOps', mongodb: 'Backend & DevOps', sentry: 'Backend & DevOps',\n posthog: 'Backend & DevOps', hashicorp: 'Backend & DevOps', clickhouse: 'Backend & DevOps',\n composio: 'Backend & DevOps', sanity: 'Backend & DevOps',\n notion: 'Productivity', 'linear.app': 'Productivity', 'cal': 'Productivity',\n zapier: 'Productivity', intercom: 'Productivity', resend: 'Productivity', mintlify: 'Productivity',\n figma: 'Design Tools', framer: 'Design Tools', miro: 'Design Tools',\n webflow: 'Design Tools', airtable: 'Design Tools', clay: 'Design Tools',\n claude: 'AI & LLM', cohere: 'AI & LLM', mistral: 'AI & LLM', 'mistral.ai': 'AI & LLM',\n ollama: 'AI & LLM', 'opencode.ai': 'AI & LLM', replicate: 'AI & LLM',\n 'together.ai': 'AI & LLM', 'x.ai': 'AI & LLM', elevenlabs: 'AI & LLM',\n minimax: 'AI & LLM', runwayml: 'AI & LLM', voltagent: 'AI & LLM',\n apple: 'Consumer Tech', spotify: 'Consumer Tech', uber: 'Consumer Tech',\n airbnb: 'Consumer Tech', pinterest: 'Consumer Tech', nvidia: 'Consumer Tech',\n ibm: 'Consumer Tech', spacex: 'Consumer Tech',\n shopify: 'E-commerce', semrush: 'Marketing',\n tesla: 'Automotive', bmw: 'Automotive', ferrari: 'Automotive',\n lamborghini: 'Automotive', renault: 'Automotive', bugatti: 'Automotive',\n karrot: 'Korean Tech', toss: 'Korean Tech', baemin: 'Korean Tech', kakao: 'Korean Tech',\n};\n\nconst CATEGORY_ORDER = [\n 'Korean Tech', 'AI & LLM', 'Design Tools', 'Developer Tools',\n 'Productivity', 'Consumer Tech', 'Fintech', 'Backend & DevOps',\n 'E-commerce', 'Automotive', 'Marketing',\n];\n\n// ── Extraction helpers ───────────────────────────────────────────\n\nfunction extractHexColors(text: string): string[] {\n const matches = text.match(/#[0-9a-fA-F]{6}\\b/g) || [];\n return [...new Set(matches)];\n}\n\nfunction extractPrimaryColor(md: string): { hex: string; name: string } {\n // Look for the first color in section 2 with \"Primary\" or \"Brand\" in its description\n const section2Match = md.match(/## 2\\. Color Palette.*?\\n([\\s\\S]*?)(?=## 3\\.)/);\n if (section2Match) {\n const section2 = section2Match[1];\n // Pattern: **Name** (`#hex`): description with \"primary\" or \"brand\" or \"CTA\"\n const primaryMatch = section2.match(/\\*\\*([^*]+)\\*\\*\\s*\\(`(#[0-9a-fA-F]{6})`\\).*?(?:primary|brand|CTA|main)/i);\n if (primaryMatch) {\n return { hex: primaryMatch[2], name: primaryMatch[1] };\n }\n // Fallback: first hex in section 2\n const firstHex = section2.match(/`(#[0-9a-fA-F]{6})`/);\n if (firstHex) {\n return { hex: firstHex[1], name: 'Primary' };\n }\n }\n const allHex = extractHexColors(md);\n return { hex: allHex[0] || '#6366f1', name: 'Primary' };\n}\n\nfunction extractBackground(md: string): string {\n // Try specific page/canvas background patterns first (avoid matching component backgrounds)\n const patterns = [\n /(?:page|canvas|marketing)\\s+background.*?`(#[0-9a-fA-F]{6})`/i,\n /(?:Pure White|White).*?`(#[0-9a-fA-F]{6})`.*?(?:page background|background)/i,\n /Background:.*?Pure White.*?\\(`(#[0-9a-fA-F]{6})`\\)/i,\n /(?:Page|Site)\\s+background.*?`(#[0-9a-fA-F]{6})`/i,\n // Match \"hex: The primary page background\" pattern (hex before description)\n /`(#[0-9a-fA-F]{6})`[^.]*?(?:primary\\s+)?page\\s+background/i,\n ];\n for (const pattern of patterns) {\n const match = md.match(pattern);\n if (match) return match[1];\n }\n // Look in Section 2 for surface/background colors\n const section2 = md.match(/## 2\\. Color.*?\\n([\\s\\S]*?)(?=## 3\\.)/);\n if (section2) {\n const surfaceBg = section2[1].match(/(?:Pure White|Pure Black|page background|Background\\b).*?`(#[0-9a-fA-F]{6})`/i);\n if (surfaceBg) return surfaceBg[1];\n }\n // Check Quick Color Reference section for background (supports both backtick and parenthesis hex)\n const quickRef = md.match(/Quick Color Reference[\\s\\S]*?(?:Page\\s+)?Background.*?[(`](#[0-9a-fA-F]{6})[)`]/i);\n if (quickRef) return quickRef[1];\n // Fallback: if the design mentions dark-mode-native, use dark bg\n if (md.match(/dark.mode.(?:native|first)/i)) {\n const darkBg = md.match(/(?:marketing|deepest|canvas).*?`(#[0-9a-fA-F]{6})`/i);\n if (darkBg) return darkBg[1];\n }\n return '#ffffff';\n}\n\nfunction extractForeground(md: string): string {\n const fgMatch = md.match(/(?:heading|primary text).*?`(#[0-9a-fA-F]{6})`/i);\n return fgMatch ? fgMatch[1] : '#09090b';\n}\n\nfunction extractAccent(md: string): string | undefined {\n const accentMatch = md.match(/(?:accent|secondary).*?`(#[0-9a-fA-F]{6})`/i);\n return accentMatch ? accentMatch[1] : undefined;\n}\n\nfunction extractBorder(md: string): string | undefined {\n const borderMatch = md.match(/(?:border.*?default|border.*?standard).*?`(#[0-9a-fA-F]{6})`/i);\n return borderMatch ? borderMatch[1] : undefined;\n}\n\nfunction extractTypography(md: string): ExtractedTypography {\n const section3 = md.match(/## 3\\. Typography.*?\\n([\\s\\S]*?)(?=## 4\\.)/);\n let primary = 'Inter';\n let mono: string | undefined;\n let headingWeight = '600';\n\n if (section3) {\n const text = section3[1];\n const primaryMatch = text.match(/\\*\\*Primary\\*\\*:\\s*`([^`]+)`/i);\n if (primaryMatch) primary = primaryMatch[1].split(',')[0].trim();\n\n const monoMatch = text.match(/\\*\\*Monospace\\*\\*:\\s*`([^`]+)`/i);\n if (monoMatch) mono = monoMatch[1].split(',')[0].trim();\n\n // Look for heading weight in hierarchy table\n const weightMatch = text.match(/Display.*?\\|\\s*(\\d{3})\\s*\\|/);\n if (weightMatch) headingWeight = weightMatch[1];\n }\n\n return { primary, mono, headingWeight };\n}\n\nfunction extractRadius(md: string): string {\n const radiusMatch = md.match(/(?:border-radius|radius).*?(\\d+px(?:\\s*[-–]\\s*\\d+px)?)/i);\n return radiusMatch ? radiusMatch[1] : '6px';\n}\n\nfunction extractMood(md: string): string {\n const section1 = md.match(/## 1\\. Visual Theme.*?\\n([\\s\\S]*?)(?=## 2\\.)/);\n if (!section1) return '';\n // First sentence or two\n const text = section1[1].trim();\n const firstParagraph = text.split('\\n\\n')[0];\n return firstParagraph.slice(0, 300);\n}\n\nfunction toDisplayName(id: string): string {\n const special: Record<string, string> = {\n 'linear.app': 'Linear', 'cal': 'Cal.com', 'mistral.ai': 'Mistral AI',\n 'opencode.ai': 'OpenCode AI', 'together.ai': 'Together AI',\n 'x.ai': 'xAI', ibm: 'IBM', bmw: 'BMW', nvidia: 'NVIDIA',\n posthog: 'PostHog', supabase: 'Supabase', voltagent: 'VoltAgent',\n elevenlabs: 'ElevenLabs', runwayml: 'RunwayML', spacex: 'SpaceX',\n coinbase: 'Coinbase', airbnb: 'Airbnb', clickhouse: 'ClickHouse',\n karrot: 'Karrot', toss: 'Toss', baemin: 'Baemin', kakao: 'Kakao',\n };\n return special[id] || id.charAt(0).toUpperCase() + id.slice(1);\n}\n\n// ── Main API ─────────────────────────────────────────────────────\n\nfunction getReferencesDir(): string {\n // Try multiple locations:\n // 1. Current working directory (project root)\n // 2. Relative to this compiled file (dist/core/ → ../../references)\n // 3. Inside the installed npm package (npx installs to node_modules)\n const candidates = [\n join(process.cwd(), 'references'),\n join(__dirname, '..', '..', 'references'),\n join(__dirname, '..', 'references'),\n ];\n for (const dir of candidates) {\n if (existsSync(dir)) return dir;\n }\n throw new Error('references/ directory not found. Searched: ' + candidates.join(', '));\n}\n\nexport function loadReference(id: string): ReferenceEntry {\n const dir = getReferencesDir();\n const mdPath = join(dir, id, 'DESIGN.md');\n if (!existsSync(mdPath)) {\n throw new Error(`Reference not found: ${id}`);\n }\n\n const designMd = readFileSync(mdPath, 'utf-8');\n const primary = extractPrimaryColor(designMd);\n\n return {\n id,\n name: toDisplayName(id),\n category: CATEGORIES[id] || 'Other',\n designMd,\n colors: {\n primary: primary.hex,\n primaryName: primary.name,\n background: extractBackground(designMd),\n foreground: extractForeground(designMd),\n accent: extractAccent(designMd),\n border: extractBorder(designMd),\n },\n typography: extractTypography(designMd),\n radius: extractRadius(designMd),\n mood: extractMood(designMd),\n };\n}\n\nexport function listReferences(): Array<{ id: string; name: string; category: string; primaryColor: string }> {\n const dir = getReferencesDir();\n const entries = readdirSync(dir, { withFileTypes: true })\n .filter((d) => d.isDirectory() && existsSync(join(dir, d.name, 'DESIGN.md')))\n .map((d) => {\n const mdPath = join(dir, d.name, 'DESIGN.md');\n const md = readFileSync(mdPath, 'utf-8');\n const primary = extractPrimaryColor(md);\n return {\n id: d.name,\n name: toDisplayName(d.name),\n category: CATEGORIES[d.name] || 'Other',\n primaryColor: primary.hex,\n };\n });\n\n // Sort by category order, then name\n return entries.sort((a, b) => {\n const ai = CATEGORY_ORDER.indexOf(a.category);\n const bi = CATEGORY_ORDER.indexOf(b.category);\n const oa = ai === -1 ? 999 : ai;\n const ob = bi === -1 ? 999 : bi;\n return oa - ob || a.name.localeCompare(b.name);\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/core/sync-marker.ts
4
- import { createHash } from "crypto";
5
- var BLOCK_RE = /<!-- omd:start v=(\d+) hash=([a-f0-9]+) -->\n?([\s\S]*?)\n?<!-- omd:end -->/;
6
- function hashContent(content) {
7
- return createHash("sha256").update(content, "utf8").digest("hex").slice(0, 12);
8
- }
9
- function parseBlock(fileContent) {
10
- const m = BLOCK_RE.exec(fileContent);
11
- if (!m) return null;
12
- return {
13
- version: Number(m[1]),
14
- hash: m[2],
15
- content: m[3],
16
- rawStart: m.index,
17
- rawEnd: m.index + m[0].length
18
- };
19
- }
20
- function hasDrift(block) {
21
- return hashContent(block.content) !== block.hash;
22
- }
23
- function writeBlock(fileContent, managedContent, version) {
24
- const hash = hashContent(managedContent);
25
- const block = `<!-- omd:start v=${version} hash=${hash} -->
26
- ${managedContent}
27
- <!-- omd:end -->`;
28
- const existing = parseBlock(fileContent);
29
- if (existing) {
30
- const updated = fileContent.slice(0, existing.rawStart) + block + fileContent.slice(existing.rawEnd);
31
- return { updated, hash };
32
- }
33
- if (fileContent === "") {
34
- return { updated: block + "\n", hash };
35
- }
36
- const sep = fileContent.endsWith("\n\n") ? "" : fileContent.endsWith("\n") ? "\n" : "\n\n";
37
- return { updated: fileContent + sep + block + "\n", hash };
38
- }
39
-
40
- export {
41
- hashContent,
42
- parseBlock,
43
- hasDrift,
44
- writeBlock
45
- };
46
- //# sourceMappingURL=chunk-OOQQEUGX.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/sync-marker.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nexport interface ManagedBlock {\n version: number;\n hash: string;\n content: string;\n rawStart: number;\n rawEnd: number;\n}\n\nexport interface WriteBlockResult {\n updated: string;\n hash: string;\n}\n\nconst BLOCK_RE =\n /<!-- omd:start v=(\\d+) hash=([a-f0-9]+) -->\\n?([\\s\\S]*?)\\n?<!-- omd:end -->/;\n\nexport function hashContent(content: string): string {\n return createHash('sha256').update(content, 'utf8').digest('hex').slice(0, 12);\n}\n\nexport function parseBlock(fileContent: string): ManagedBlock | null {\n const m = BLOCK_RE.exec(fileContent);\n if (!m) return null;\n return {\n version: Number(m[1]),\n hash: m[2],\n content: m[3],\n rawStart: m.index,\n rawEnd: m.index + m[0].length,\n };\n}\n\nexport function hasDrift(block: ManagedBlock): boolean {\n return hashContent(block.content) !== block.hash;\n}\n\nexport function writeBlock(\n fileContent: string,\n managedContent: string,\n version: number\n): WriteBlockResult {\n const hash = hashContent(managedContent);\n const block = `<!-- omd:start v=${version} hash=${hash} -->\\n${managedContent}\\n<!-- omd:end -->`;\n\n const existing = parseBlock(fileContent);\n if (existing) {\n const updated =\n fileContent.slice(0, existing.rawStart) +\n block +\n fileContent.slice(existing.rawEnd);\n return { updated, hash };\n }\n\n if (fileContent === '') {\n return { updated: block + '\\n', hash };\n }\n\n const sep = fileContent.endsWith('\\n\\n')\n ? ''\n : fileContent.endsWith('\\n')\n ? '\\n'\n : '\\n\\n';\n return { updated: fileContent + sep + block + '\\n', hash };\n}\n"],"mappings":";;;AAAA,SAAS,kBAAkB;AAe3B,IAAM,WACJ;AAEK,SAAS,YAAY,SAAyB;AACnD,SAAO,WAAW,QAAQ,EAAE,OAAO,SAAS,MAAM,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC/E;AAEO,SAAS,WAAW,aAA0C;AACnE,QAAM,IAAI,SAAS,KAAK,WAAW;AACnC,MAAI,CAAC,EAAG,QAAO;AACf,SAAO;AAAA,IACL,SAAS,OAAO,EAAE,CAAC,CAAC;AAAA,IACpB,MAAM,EAAE,CAAC;AAAA,IACT,SAAS,EAAE,CAAC;AAAA,IACZ,UAAU,EAAE;AAAA,IACZ,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE;AAAA,EACzB;AACF;AAEO,SAAS,SAAS,OAA8B;AACrD,SAAO,YAAY,MAAM,OAAO,MAAM,MAAM;AAC9C;AAEO,SAAS,WACd,aACA,gBACA,SACkB;AAClB,QAAM,OAAO,YAAY,cAAc;AACvC,QAAM,QAAQ,oBAAoB,OAAO,SAAS,IAAI;AAAA,EAAS,cAAc;AAAA;AAE7E,QAAM,WAAW,WAAW,WAAW;AACvC,MAAI,UAAU;AACZ,UAAM,UACJ,YAAY,MAAM,GAAG,SAAS,QAAQ,IACtC,QACA,YAAY,MAAM,SAAS,MAAM;AACnC,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAEA,MAAI,gBAAgB,IAAI;AACtB,WAAO,EAAE,SAAS,QAAQ,MAAM,KAAK;AAAA,EACvC;AAEA,QAAM,MAAM,YAAY,SAAS,MAAM,IACnC,KACA,YAAY,SAAS,IAAI,IACvB,OACA;AACN,SAAO,EAAE,SAAS,cAAc,MAAM,QAAQ,MAAM,KAAK;AAC3D;","names":[]}
@@ -1,250 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/core/preferences.ts
4
- import {
5
- readFileSync,
6
- writeFileSync,
7
- mkdirSync,
8
- existsSync
9
- } from "fs";
10
- import { randomBytes } from "crypto";
11
- import { dirname, join } from "path";
12
- var PREFERENCES_PATH = ".omd/preferences.md";
13
- var PREFERENCES_SCHEMA = "omd.preferences/v1";
14
- function prefPath(projectRoot) {
15
- return join(projectRoot, PREFERENCES_PATH);
16
- }
17
- function generateId() {
18
- const ts = Date.now().toString(36);
19
- const rand = randomBytes(4).toString("hex");
20
- return `pref_${ts}_${rand}`;
21
- }
22
- function slugify(input, max = 40) {
23
- return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, max) || "entry";
24
- }
25
- var SCOPE_KEYWORDS = [
26
- [/\b(buttons?|ctas?|btns?)\b/i, "components.button"],
27
- [/\b(cards?)\b/i, "components.card"],
28
- [/\b(dialogs?|modals?)\b/i, "components.dialog"],
29
- [/\b(inputs?|fields?|forms?)\b/i, "components.input"],
30
- [/\b(nav|navigation|headers?|menus?)\b/i, "components.navigation"],
31
- [/\b(badges?|chips?|pills?|tags?)\b/i, "components.badge"],
32
- [/\b(tables?|rows?|cells?)\b/i, "components.table"],
33
- [/\b(dropdowns?|selects?|comboboxes?)\b/i, "components.dropdown"],
34
- [/\b(toasts?|notifications?|snackbars?)\b/i, "components.toast"],
35
- [/\b(tabs?)\b/i, "components.tabs"],
36
- [/\b(colors?|palette|hex|hue|saturation|shades?|tints?|gradients?)\b/i, "color"],
37
- [/\b(font|typography|typeface|weight|leading|tracking|letter-?spacing)\b/i, "typography"],
38
- [/\b(spacing|gap|padding|margin|grid)\b/i, "spacing"],
39
- [/\b(voice|tone|copy|microcopy|wording|language)\b/i, "voice"],
40
- [/\b(motion|animation|transition|easing|duration)\b/i, "motion"],
41
- [/\b(layout|structure|hierarchy)\b/i, "layout"],
42
- [/\b(theme|aesthetic|vibe|mood|look|feel)\b/i, "visualTheme"]
43
- ];
44
- function inferScope(note) {
45
- for (const [re, scope] of SCOPE_KEYWORDS) {
46
- if (re.test(note)) return scope;
47
- }
48
- return "visualTheme";
49
- }
50
- function renderMeta(meta) {
51
- const lines = [];
52
- lines.push(`id: ${meta.id}`);
53
- lines.push(`timestamp: ${meta.timestamp}`);
54
- lines.push(`scope: ${meta.scope}`);
55
- lines.push(`signal: ${meta.signal}`);
56
- lines.push(`confidence: ${meta.confidence}`);
57
- lines.push(`status: ${meta.status}`);
58
- if (meta.source_agent) lines.push(`source_agent: ${meta.source_agent}`);
59
- if (meta.source_context)
60
- lines.push(`source_context: ${JSON.stringify(meta.source_context)}`);
61
- if (meta.applied_design_md_hash)
62
- lines.push(`applied_design_md_hash: ${meta.applied_design_md_hash}`);
63
- if (meta.applied_at) lines.push(`applied_at: ${meta.applied_at}`);
64
- if (meta.rejected_reason)
65
- lines.push(`rejected_reason: ${JSON.stringify(meta.rejected_reason)}`);
66
- if (meta.superseded_by) lines.push(`superseded_by: ${meta.superseded_by}`);
67
- return lines.join("\n");
68
- }
69
- function renderEntry(entry) {
70
- return `## ${entry.heading}
71
-
72
- \`\`\`omd-meta
73
- ` + renderMeta(entry.meta) + "\n```\n\n" + entry.body.trim() + "\n";
74
- }
75
- function renderFile(file) {
76
- const header = `---
77
- schema: ${file.schema}
78
- design_md_hash_at_creation: ${file.design_md_hash_at_creation}
79
- ---
80
-
81
- # Preference Log
82
-
83
- `;
84
- const body = file.entries.map(renderEntry).join("\n");
85
- return header + body;
86
- }
87
- var FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n?/;
88
- var ENTRY_SPLIT_RE = /^## /m;
89
- var META_BLOCK_RE = /```omd-meta\n([\s\S]*?)\n```/;
90
- function parseFrontmatter(raw) {
91
- const m = FRONTMATTER_RE.exec(raw);
92
- if (!m) return { fields: {}, rest: raw };
93
- const fields = {};
94
- for (const line of m[1].split("\n")) {
95
- const idx = line.indexOf(":");
96
- if (idx === -1) continue;
97
- const key = line.slice(0, idx).trim();
98
- const val = line.slice(idx + 1).trim();
99
- fields[key] = val;
100
- }
101
- return { fields, rest: raw.slice(m[0].length) };
102
- }
103
- function parseMetaBlock(text) {
104
- const m = META_BLOCK_RE.exec(text);
105
- if (!m) return {};
106
- const fields = {};
107
- for (const line of m[1].split("\n")) {
108
- const idx = line.indexOf(":");
109
- if (idx === -1) continue;
110
- const key = line.slice(0, idx).trim();
111
- let val = line.slice(idx + 1).trim();
112
- if (val.startsWith('"') && val.endsWith('"')) {
113
- try {
114
- val = JSON.parse(val);
115
- } catch {
116
- }
117
- }
118
- fields[key] = val;
119
- }
120
- return fields;
121
- }
122
- function parseEntry(chunk) {
123
- const newline = chunk.indexOf("\n");
124
- const heading = (newline === -1 ? chunk : chunk.slice(0, newline)).trim();
125
- const rest = newline === -1 ? "" : chunk.slice(newline + 1);
126
- const metaFields = parseMetaBlock(rest);
127
- if (!metaFields.id) return null;
128
- const bodyStart = rest.search(META_BLOCK_RE);
129
- const metaEnd = bodyStart >= 0 ? bodyStart + (META_BLOCK_RE.exec(rest.slice(bodyStart))?.[0].length ?? 0) : 0;
130
- const body = rest.slice(metaEnd).trim();
131
- return {
132
- heading,
133
- body,
134
- meta: {
135
- id: metaFields.id,
136
- timestamp: metaFields.timestamp ?? "",
137
- scope: metaFields.scope ?? "visualTheme",
138
- signal: metaFields.signal ?? "user-statement",
139
- confidence: metaFields.confidence ?? "explicit",
140
- status: metaFields.status ?? "pending",
141
- source_agent: metaFields.source_agent,
142
- source_context: metaFields.source_context,
143
- applied_design_md_hash: metaFields.applied_design_md_hash,
144
- applied_at: metaFields.applied_at,
145
- rejected_reason: metaFields.rejected_reason,
146
- superseded_by: metaFields.superseded_by
147
- }
148
- };
149
- }
150
- function parseFile(raw) {
151
- const { fields, rest } = parseFrontmatter(raw);
152
- const schema = fields.schema || PREFERENCES_SCHEMA;
153
- const design_md_hash_at_creation = fields.design_md_hash_at_creation ?? "";
154
- const chunks = rest.split(ENTRY_SPLIT_RE).slice(1);
155
- const entries = chunks.map((c) => parseEntry(c)).filter((e) => e !== null);
156
- return { schema, design_md_hash_at_creation, entries };
157
- }
158
- function readFile(projectRoot) {
159
- const path = prefPath(projectRoot);
160
- if (!existsSync(path)) return null;
161
- return parseFile(readFileSync(path, "utf8"));
162
- }
163
- function writeFile(projectRoot, file) {
164
- const path = prefPath(projectRoot);
165
- mkdirSync(dirname(path), { recursive: true });
166
- writeFileSync(path, renderFile(file), "utf8");
167
- }
168
- function buildEntry(input) {
169
- const now = input.now ?? /* @__PURE__ */ new Date();
170
- const timestamp = now.toISOString();
171
- const scope = input.scope ?? inferScope(input.note);
172
- const slug = slugify(input.note);
173
- const heading = `${timestamp} \u2014 ${slug}`;
174
- return {
175
- heading,
176
- body: input.note.trim(),
177
- meta: {
178
- id: generateId(),
179
- timestamp,
180
- scope,
181
- signal: input.signal ?? "user-statement",
182
- confidence: input.confidence ?? "explicit",
183
- status: "pending",
184
- source_agent: input.source_agent,
185
- source_context: input.source_context
186
- }
187
- };
188
- }
189
- function updateEntryStatus(projectRoot, input) {
190
- const file = readFile(projectRoot);
191
- if (!file) {
192
- throw new Error(
193
- `no preferences file found at ${projectRoot}/${PREFERENCES_PATH}`
194
- );
195
- }
196
- const entry = file.entries.find((e) => e.meta.id === input.id);
197
- if (!entry) {
198
- throw new Error(`preference id not found: ${input.id}`);
199
- }
200
- const now = (input.now ?? /* @__PURE__ */ new Date()).toISOString();
201
- entry.meta.status = input.status;
202
- if (input.status === "applied") {
203
- entry.meta.applied_at = now;
204
- if (input.applied_design_md_hash) {
205
- entry.meta.applied_design_md_hash = input.applied_design_md_hash;
206
- }
207
- }
208
- if (input.status === "rejected" && input.rejected_reason) {
209
- entry.meta.rejected_reason = input.rejected_reason;
210
- }
211
- if (input.status === "superseded" && input.superseded_by) {
212
- entry.meta.superseded_by = input.superseded_by;
213
- }
214
- writeFile(projectRoot, file);
215
- return entry;
216
- }
217
- function groupByScope(entries) {
218
- const map = /* @__PURE__ */ new Map();
219
- for (const entry of entries) {
220
- const bucket = map.get(entry.meta.scope);
221
- if (bucket) bucket.push(entry);
222
- else map.set(entry.meta.scope, [entry]);
223
- }
224
- return map;
225
- }
226
- function filterByStatus(entries, status) {
227
- return entries.filter((e) => e.meta.status === status);
228
- }
229
- function appendEntry(projectRoot, input, designMdHashIfNew = "") {
230
- const existing = readFile(projectRoot);
231
- const entry = buildEntry(input);
232
- const file = existing ?? {
233
- schema: PREFERENCES_SCHEMA,
234
- design_md_hash_at_creation: designMdHashIfNew,
235
- entries: []
236
- };
237
- file.entries.push(entry);
238
- writeFile(projectRoot, file);
239
- return entry;
240
- }
241
-
242
- export {
243
- inferScope,
244
- readFile,
245
- updateEntryStatus,
246
- groupByScope,
247
- filterByStatus,
248
- appendEntry
249
- };
250
- //# sourceMappingURL=chunk-OR5DHENY.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/preferences.ts"],"sourcesContent":["import {\n readFileSync,\n writeFileSync,\n mkdirSync,\n existsSync,\n} from 'node:fs';\nimport { randomBytes } from 'node:crypto';\nimport { dirname, join } from 'node:path';\n\nexport const PREFERENCES_PATH = '.omd/preferences.md';\nexport const PREFERENCES_SCHEMA = 'omd.preferences/v1';\n\nexport type PreferenceScope =\n | 'visualTheme'\n | 'color'\n | 'typography'\n | 'spacing'\n | 'voice'\n | 'motion'\n | 'layout'\n | `components.${string}`;\n\nexport type PreferenceSignal =\n | 'user-correction'\n | 'user-statement'\n | 'inferred-from-revert'\n | 'inferred-from-edit';\n\nexport type PreferenceConfidence = 'explicit' | 'inferred';\n\nexport type PreferenceStatus =\n | 'pending'\n | 'applied'\n | 'rejected'\n | 'superseded';\n\nexport interface PreferenceMeta {\n id: string;\n timestamp: string;\n scope: PreferenceScope;\n signal: PreferenceSignal;\n confidence: PreferenceConfidence;\n status: PreferenceStatus;\n source_agent?: string;\n source_context?: string;\n applied_design_md_hash?: string;\n applied_at?: string;\n rejected_reason?: string;\n superseded_by?: string;\n}\n\nexport interface PreferenceEntry {\n meta: PreferenceMeta;\n heading: string;\n body: string;\n}\n\nexport interface PreferencesFile {\n schema: string;\n design_md_hash_at_creation: string;\n entries: PreferenceEntry[];\n}\n\nfunction prefPath(projectRoot: string): string {\n return join(projectRoot, PREFERENCES_PATH);\n}\n\nexport function generateId(): string {\n const ts = Date.now().toString(36);\n const rand = randomBytes(4).toString('hex');\n return `pref_${ts}_${rand}`;\n}\n\nexport function slugify(input: string, max = 40): string {\n return input\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, max) || 'entry';\n}\n\nconst SCOPE_KEYWORDS: Array<[RegExp, PreferenceScope]> = [\n [/\\b(buttons?|ctas?|btns?)\\b/i, 'components.button'],\n [/\\b(cards?)\\b/i, 'components.card'],\n [/\\b(dialogs?|modals?)\\b/i, 'components.dialog'],\n [/\\b(inputs?|fields?|forms?)\\b/i, 'components.input'],\n [/\\b(nav|navigation|headers?|menus?)\\b/i, 'components.navigation'],\n [/\\b(badges?|chips?|pills?|tags?)\\b/i, 'components.badge'],\n [/\\b(tables?|rows?|cells?)\\b/i, 'components.table'],\n [/\\b(dropdowns?|selects?|comboboxes?)\\b/i, 'components.dropdown'],\n [/\\b(toasts?|notifications?|snackbars?)\\b/i, 'components.toast'],\n [/\\b(tabs?)\\b/i, 'components.tabs'],\n [/\\b(colors?|palette|hex|hue|saturation|shades?|tints?|gradients?)\\b/i, 'color'],\n [/\\b(font|typography|typeface|weight|leading|tracking|letter-?spacing)\\b/i, 'typography'],\n [/\\b(spacing|gap|padding|margin|grid)\\b/i, 'spacing'],\n [/\\b(voice|tone|copy|microcopy|wording|language)\\b/i, 'voice'],\n [/\\b(motion|animation|transition|easing|duration)\\b/i, 'motion'],\n [/\\b(layout|structure|hierarchy)\\b/i, 'layout'],\n [/\\b(theme|aesthetic|vibe|mood|look|feel)\\b/i, 'visualTheme'],\n];\n\nexport function inferScope(note: string): PreferenceScope {\n for (const [re, scope] of SCOPE_KEYWORDS) {\n if (re.test(note)) return scope;\n }\n return 'visualTheme';\n}\n\nfunction renderMeta(meta: PreferenceMeta): string {\n const lines: string[] = [];\n lines.push(`id: ${meta.id}`);\n lines.push(`timestamp: ${meta.timestamp}`);\n lines.push(`scope: ${meta.scope}`);\n lines.push(`signal: ${meta.signal}`);\n lines.push(`confidence: ${meta.confidence}`);\n lines.push(`status: ${meta.status}`);\n if (meta.source_agent) lines.push(`source_agent: ${meta.source_agent}`);\n if (meta.source_context)\n lines.push(`source_context: ${JSON.stringify(meta.source_context)}`);\n if (meta.applied_design_md_hash)\n lines.push(`applied_design_md_hash: ${meta.applied_design_md_hash}`);\n if (meta.applied_at) lines.push(`applied_at: ${meta.applied_at}`);\n if (meta.rejected_reason)\n lines.push(`rejected_reason: ${JSON.stringify(meta.rejected_reason)}`);\n if (meta.superseded_by) lines.push(`superseded_by: ${meta.superseded_by}`);\n return lines.join('\\n');\n}\n\nexport function renderEntry(entry: PreferenceEntry): string {\n return (\n `## ${entry.heading}\\n\\n` +\n '```omd-meta\\n' +\n renderMeta(entry.meta) +\n '\\n```\\n\\n' +\n entry.body.trim() +\n '\\n'\n );\n}\n\nexport function renderFile(file: PreferencesFile): string {\n const header =\n `---\\n` +\n `schema: ${file.schema}\\n` +\n `design_md_hash_at_creation: ${file.design_md_hash_at_creation}\\n` +\n `---\\n\\n` +\n `# Preference Log\\n\\n`;\n const body = file.entries.map(renderEntry).join('\\n');\n return header + body;\n}\n\nconst FRONTMATTER_RE = /^---\\n([\\s\\S]*?)\\n---\\n?/;\nconst ENTRY_SPLIT_RE = /^## /m;\nconst META_BLOCK_RE = /```omd-meta\\n([\\s\\S]*?)\\n```/;\n\nfunction parseFrontmatter(raw: string): {\n fields: Record<string, string>;\n rest: string;\n} {\n const m = FRONTMATTER_RE.exec(raw);\n if (!m) return { fields: {}, rest: raw };\n const fields: Record<string, string> = {};\n for (const line of m[1].split('\\n')) {\n const idx = line.indexOf(':');\n if (idx === -1) continue;\n const key = line.slice(0, idx).trim();\n const val = line.slice(idx + 1).trim();\n fields[key] = val;\n }\n return { fields, rest: raw.slice(m[0].length) };\n}\n\nfunction parseMetaBlock(text: string): Record<string, string> {\n const m = META_BLOCK_RE.exec(text);\n if (!m) return {};\n const fields: Record<string, string> = {};\n for (const line of m[1].split('\\n')) {\n const idx = line.indexOf(':');\n if (idx === -1) continue;\n const key = line.slice(0, idx).trim();\n let val = line.slice(idx + 1).trim();\n if (val.startsWith('\"') && val.endsWith('\"')) {\n try {\n val = JSON.parse(val);\n } catch {\n // keep as-is\n }\n }\n fields[key] = val;\n }\n return fields;\n}\n\nfunction parseEntry(chunk: string): PreferenceEntry | null {\n const newline = chunk.indexOf('\\n');\n const heading = (newline === -1 ? chunk : chunk.slice(0, newline)).trim();\n const rest = newline === -1 ? '' : chunk.slice(newline + 1);\n const metaFields = parseMetaBlock(rest);\n if (!metaFields.id) return null;\n\n const bodyStart = rest.search(META_BLOCK_RE);\n const metaEnd =\n bodyStart >= 0\n ? bodyStart + (META_BLOCK_RE.exec(rest.slice(bodyStart))?.[0].length ?? 0)\n : 0;\n const body = rest.slice(metaEnd).trim();\n\n return {\n heading,\n body,\n meta: {\n id: metaFields.id,\n timestamp: metaFields.timestamp ?? '',\n scope: (metaFields.scope as PreferenceScope) ?? 'visualTheme',\n signal: (metaFields.signal as PreferenceSignal) ?? 'user-statement',\n confidence:\n (metaFields.confidence as PreferenceConfidence) ?? 'explicit',\n status: (metaFields.status as PreferenceStatus) ?? 'pending',\n source_agent: metaFields.source_agent,\n source_context: metaFields.source_context,\n applied_design_md_hash: metaFields.applied_design_md_hash,\n applied_at: metaFields.applied_at,\n rejected_reason: metaFields.rejected_reason,\n superseded_by: metaFields.superseded_by,\n },\n };\n}\n\nexport function parseFile(raw: string): PreferencesFile {\n const { fields, rest } = parseFrontmatter(raw);\n const schema = fields.schema || PREFERENCES_SCHEMA;\n const design_md_hash_at_creation = fields.design_md_hash_at_creation ?? '';\n\n const chunks = rest.split(ENTRY_SPLIT_RE).slice(1);\n const entries = chunks\n .map((c) => parseEntry(c))\n .filter((e): e is PreferenceEntry => e !== null);\n\n return { schema, design_md_hash_at_creation, entries };\n}\n\nexport function readFile(projectRoot: string): PreferencesFile | null {\n const path = prefPath(projectRoot);\n if (!existsSync(path)) return null;\n return parseFile(readFileSync(path, 'utf8'));\n}\n\nexport function writeFile(\n projectRoot: string,\n file: PreferencesFile\n): void {\n const path = prefPath(projectRoot);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, renderFile(file), 'utf8');\n}\n\nexport interface CreateEntryInput {\n note: string;\n scope?: PreferenceScope;\n signal?: PreferenceSignal;\n confidence?: PreferenceConfidence;\n source_agent?: string;\n source_context?: string;\n now?: Date;\n}\n\nexport function buildEntry(input: CreateEntryInput): PreferenceEntry {\n const now = input.now ?? new Date();\n const timestamp = now.toISOString();\n const scope = input.scope ?? inferScope(input.note);\n const slug = slugify(input.note);\n const heading = `${timestamp} — ${slug}`;\n\n return {\n heading,\n body: input.note.trim(),\n meta: {\n id: generateId(),\n timestamp,\n scope,\n signal: input.signal ?? 'user-statement',\n confidence: input.confidence ?? 'explicit',\n status: 'pending',\n source_agent: input.source_agent,\n source_context: input.source_context,\n },\n };\n}\n\nexport interface UpdateStatusInput {\n id: string;\n status: PreferenceStatus;\n applied_design_md_hash?: string;\n rejected_reason?: string;\n superseded_by?: string;\n now?: Date;\n}\n\nexport function updateEntryStatus(\n projectRoot: string,\n input: UpdateStatusInput\n): PreferenceEntry {\n const file = readFile(projectRoot);\n if (!file) {\n throw new Error(\n `no preferences file found at ${projectRoot}/${PREFERENCES_PATH}`\n );\n }\n\n const entry = file.entries.find((e) => e.meta.id === input.id);\n if (!entry) {\n throw new Error(`preference id not found: ${input.id}`);\n }\n\n const now = (input.now ?? new Date()).toISOString();\n entry.meta.status = input.status;\n\n if (input.status === 'applied') {\n entry.meta.applied_at = now;\n if (input.applied_design_md_hash) {\n entry.meta.applied_design_md_hash = input.applied_design_md_hash;\n }\n }\n if (input.status === 'rejected' && input.rejected_reason) {\n entry.meta.rejected_reason = input.rejected_reason;\n }\n if (input.status === 'superseded' && input.superseded_by) {\n entry.meta.superseded_by = input.superseded_by;\n }\n\n writeFile(projectRoot, file);\n return entry;\n}\n\nexport function groupByScope(\n entries: PreferenceEntry[]\n): Map<PreferenceScope, PreferenceEntry[]> {\n const map = new Map<PreferenceScope, PreferenceEntry[]>();\n for (const entry of entries) {\n const bucket = map.get(entry.meta.scope);\n if (bucket) bucket.push(entry);\n else map.set(entry.meta.scope, [entry]);\n }\n return map;\n}\n\nexport function filterByStatus(\n entries: PreferenceEntry[],\n status: PreferenceStatus\n): PreferenceEntry[] {\n return entries.filter((e) => e.meta.status === status);\n}\n\nexport function appendEntry(\n projectRoot: string,\n input: CreateEntryInput,\n designMdHashIfNew = ''\n): PreferenceEntry {\n const existing = readFile(projectRoot);\n const entry = buildEntry(input);\n\n const file: PreferencesFile = existing ?? {\n schema: PREFERENCES_SCHEMA,\n design_md_hash_at_creation: designMdHashIfNew,\n entries: [],\n };\n\n file.entries.push(entry);\n writeFile(projectRoot, file);\n return entry;\n}\n"],"mappings":"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","names":[]}
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- applyOverrides
4
- } from "./chunk-MHFYGZSO.js";
5
- export {
6
- applyOverrides
7
- };
8
- //# sourceMappingURL=customizer-CM76752R.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}