paintoliver 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/LICENSE +21 -0
- package/README.md +207 -0
- package/dist/analyzer/index.d.ts +20 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +387 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/cli.d.ts +26 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +436 -0
- package/dist/cli.js.map +1 -0
- package/dist/contrast/index.d.ts +88 -0
- package/dist/contrast/index.d.ts.map +1 -0
- package/dist/contrast/index.js +314 -0
- package/dist/contrast/index.js.map +1 -0
- package/dist/paintoliver.bundle.js +14530 -0
- package/dist/reporter/index.d.ts +43 -0
- package/dist/reporter/index.d.ts.map +1 -0
- package/dist/reporter/index.js +235 -0
- package/dist/reporter/index.js.map +1 -0
- package/dist/transformer/css-var-transformer.d.ts +46 -0
- package/dist/transformer/css-var-transformer.d.ts.map +1 -0
- package/dist/transformer/css-var-transformer.js +422 -0
- package/dist/transformer/css-var-transformer.js.map +1 -0
- package/dist/transformer/index.d.ts +17 -0
- package/dist/transformer/index.d.ts.map +1 -0
- package/dist/transformer/index.js +213 -0
- package/dist/transformer/index.js.map +1 -0
- package/dist/transformer/tailwind-transformer.d.ts +47 -0
- package/dist/transformer/tailwind-transformer.d.ts.map +1 -0
- package/dist/transformer/tailwind-transformer.js +402 -0
- package/dist/transformer/tailwind-transformer.js.map +1 -0
- package/dist/utils/backup.d.ts +41 -0
- package/dist/utils/backup.d.ts.map +1 -0
- package/dist/utils/backup.js +125 -0
- package/dist/utils/backup.js.map +1 -0
- package/dist/vibes/definitions/brutalist.d.ts +11 -0
- package/dist/vibes/definitions/brutalist.d.ts.map +1 -0
- package/dist/vibes/definitions/brutalist.js +203 -0
- package/dist/vibes/definitions/brutalist.js.map +1 -0
- package/dist/vibes/definitions/corporate.d.ts +12 -0
- package/dist/vibes/definitions/corporate.d.ts.map +1 -0
- package/dist/vibes/definitions/corporate.js +212 -0
- package/dist/vibes/definitions/corporate.js.map +1 -0
- package/dist/vibes/definitions/glassmorphism.d.ts +20 -0
- package/dist/vibes/definitions/glassmorphism.d.ts.map +1 -0
- package/dist/vibes/definitions/glassmorphism.js +217 -0
- package/dist/vibes/definitions/glassmorphism.js.map +1 -0
- package/dist/vibes/definitions/kinetic-terminal.d.ts +20 -0
- package/dist/vibes/definitions/kinetic-terminal.d.ts.map +1 -0
- package/dist/vibes/definitions/kinetic-terminal.js +242 -0
- package/dist/vibes/definitions/kinetic-terminal.js.map +1 -0
- package/dist/vibes/definitions/minimal.d.ts +11 -0
- package/dist/vibes/definitions/minimal.d.ts.map +1 -0
- package/dist/vibes/definitions/minimal.js +167 -0
- package/dist/vibes/definitions/minimal.js.map +1 -0
- package/dist/vibes/definitions/windows-xp.d.ts +12 -0
- package/dist/vibes/definitions/windows-xp.d.ts.map +1 -0
- package/dist/vibes/definitions/windows-xp.js +229 -0
- package/dist/vibes/definitions/windows-xp.js.map +1 -0
- package/dist/vibes/registry.d.ts +25 -0
- package/dist/vibes/registry.d.ts.map +1 -0
- package/dist/vibes/registry.js +52 -0
- package/dist/vibes/registry.js.map +1 -0
- package/dist/vibes/types.d.ts +428 -0
- package/dist/vibes/types.d.ts.map +1 -0
- package/dist/vibes/types.js +12 -0
- package/dist/vibes/types.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailwind Config Transformer
|
|
3
|
+
*
|
|
4
|
+
* Rewrites a project's Tailwind configuration file (v3 or v4) to reflect
|
|
5
|
+
* the selected vibe's color palette, fonts, border radius, and other tokens.
|
|
6
|
+
*
|
|
7
|
+
* For Tailwind v3: modifies tailwind.config.js theme.extend
|
|
8
|
+
* For Tailwind v4: generates/modifies @theme blocks in the main CSS file
|
|
9
|
+
*
|
|
10
|
+
* Safety rules:
|
|
11
|
+
* - Never removes existing config keys — only adds or overwrites values
|
|
12
|
+
* - Never changes `content`, `plugins`, or `safelist`
|
|
13
|
+
* - For v3, uses AST-safe string replacement rather than full parsing
|
|
14
|
+
* - For v4, appends a clearly marked @theme block rather than rewriting
|
|
15
|
+
*/
|
|
16
|
+
import fs from "fs";
|
|
17
|
+
// ─── Tailwind v4 — @theme Block ───────────────────────────────────────────────
|
|
18
|
+
const V4_THEME_BLOCK_MARKER = "/* paintoliver:theme-start */";
|
|
19
|
+
const V4_THEME_BLOCK_END_MARKER = "/* paintoliver:theme-end */";
|
|
20
|
+
/**
|
|
21
|
+
* Generate a Tailwind v4 @theme block from a vibe.
|
|
22
|
+
* This is appended to the main CSS entry point.
|
|
23
|
+
*/
|
|
24
|
+
export function generateTailwindV4ThemeBlock(vibe) {
|
|
25
|
+
const lines = [
|
|
26
|
+
"",
|
|
27
|
+
V4_THEME_BLOCK_MARKER,
|
|
28
|
+
`/* FrontEnd Agent — ${vibe.meta.name} — do not edit manually */`,
|
|
29
|
+
"@theme inline {",
|
|
30
|
+
" /* Colors */",
|
|
31
|
+
];
|
|
32
|
+
const colorMappings = [
|
|
33
|
+
["--color-background", vibe.colors.background],
|
|
34
|
+
["--color-foreground", vibe.colors.foreground],
|
|
35
|
+
["--color-primary", vibe.colors.primary],
|
|
36
|
+
["--color-primary-foreground", vibe.colors.primaryForeground],
|
|
37
|
+
["--color-secondary", vibe.colors.secondary],
|
|
38
|
+
["--color-secondary-foreground", vibe.colors.secondaryForeground],
|
|
39
|
+
["--color-card", vibe.colors.card],
|
|
40
|
+
["--color-card-foreground", vibe.colors.cardForeground],
|
|
41
|
+
["--color-muted", vibe.colors.muted],
|
|
42
|
+
["--color-muted-foreground", vibe.colors.mutedForeground],
|
|
43
|
+
["--color-accent", vibe.colors.accent],
|
|
44
|
+
["--color-accent-foreground", vibe.colors.accentForeground],
|
|
45
|
+
["--color-destructive", vibe.colors.destructive],
|
|
46
|
+
["--color-destructive-foreground", vibe.colors.destructiveForeground],
|
|
47
|
+
["--color-success", vibe.colors.success],
|
|
48
|
+
["--color-success-foreground", vibe.colors.successForeground],
|
|
49
|
+
["--color-warning", vibe.colors.warning],
|
|
50
|
+
["--color-warning-foreground", vibe.colors.warningForeground],
|
|
51
|
+
["--color-border", vibe.colors.border],
|
|
52
|
+
["--color-input", vibe.colors.input],
|
|
53
|
+
["--color-ring", vibe.colors.ring],
|
|
54
|
+
["--color-popover", vibe.colors.popover],
|
|
55
|
+
["--color-popover-foreground", vibe.colors.popoverForeground],
|
|
56
|
+
];
|
|
57
|
+
for (const [varName, value] of colorMappings) {
|
|
58
|
+
lines.push(` ${varName}: ${value};`);
|
|
59
|
+
}
|
|
60
|
+
lines.push("", " /* Typography */");
|
|
61
|
+
lines.push(` --font-family-sans: ${vibe.typography.fontFamily};`);
|
|
62
|
+
if (vibe.typography.fontFamilyHeading) {
|
|
63
|
+
lines.push(` --font-family-heading: ${vibe.typography.fontFamilyHeading};`);
|
|
64
|
+
}
|
|
65
|
+
lines.push(` --font-family-mono: ${vibe.typography.fontFamilyMono};`);
|
|
66
|
+
lines.push("", " /* Border Radius */");
|
|
67
|
+
lines.push(` --radius-none: ${vibe.radius.none};`);
|
|
68
|
+
lines.push(` --radius-sm: ${vibe.radius.sm};`);
|
|
69
|
+
lines.push(` --radius: ${vibe.radius.base};`);
|
|
70
|
+
lines.push(` --radius-md: ${vibe.radius.md};`);
|
|
71
|
+
lines.push(` --radius-lg: ${vibe.radius.lg};`);
|
|
72
|
+
lines.push(` --radius-xl: ${vibe.radius.xl};`);
|
|
73
|
+
lines.push(` --radius-2xl: ${vibe.radius["2xl"]};`);
|
|
74
|
+
lines.push(` --radius-3xl: ${vibe.radius["3xl"]};`);
|
|
75
|
+
lines.push(` --radius-full: ${vibe.radius.full};`);
|
|
76
|
+
lines.push("", " /* Shadows */");
|
|
77
|
+
lines.push(` --shadow-sm: ${vibe.shadows.sm};`);
|
|
78
|
+
lines.push(` --shadow: ${vibe.shadows.base};`);
|
|
79
|
+
lines.push(` --shadow-md: ${vibe.shadows.md};`);
|
|
80
|
+
lines.push(` --shadow-lg: ${vibe.shadows.lg};`);
|
|
81
|
+
lines.push(` --shadow-xl: ${vibe.shadows.xl};`);
|
|
82
|
+
lines.push(` --shadow-2xl: ${vibe.shadows["2xl"]};`);
|
|
83
|
+
lines.push("}");
|
|
84
|
+
lines.push(V4_THEME_BLOCK_END_MARKER);
|
|
85
|
+
return lines.join("\n");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Apply a Tailwind v4 @theme block to a CSS entry point.
|
|
89
|
+
* If a previous agent-generated block exists, replace it.
|
|
90
|
+
* Otherwise, append to the end.
|
|
91
|
+
*/
|
|
92
|
+
export function applyTailwindV4Theme(cssPath, vibe, dryRun) {
|
|
93
|
+
const changes = [];
|
|
94
|
+
let content;
|
|
95
|
+
try {
|
|
96
|
+
content = fs.readFileSync(cssPath, "utf-8");
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return changes;
|
|
100
|
+
}
|
|
101
|
+
const themeBlock = generateTailwindV4ThemeBlock(vibe);
|
|
102
|
+
const startIdx = content.indexOf(V4_THEME_BLOCK_MARKER);
|
|
103
|
+
const endIdx = content.indexOf(V4_THEME_BLOCK_END_MARKER);
|
|
104
|
+
let newContent;
|
|
105
|
+
if (startIdx !== -1 && endIdx !== -1) {
|
|
106
|
+
// Replace existing agent-generated block
|
|
107
|
+
const before = content.slice(0, startIdx).trimEnd();
|
|
108
|
+
const after = content.slice(endIdx + V4_THEME_BLOCK_END_MARKER.length);
|
|
109
|
+
newContent = before + themeBlock + after;
|
|
110
|
+
changes.push({
|
|
111
|
+
filePath: cssPath,
|
|
112
|
+
kind: "tailwind-config-updated",
|
|
113
|
+
description: `Updated Tailwind v4 @theme block with "${vibe.meta.id}" vibe tokens`,
|
|
114
|
+
reversible: true,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// Append new block
|
|
119
|
+
newContent = content.trimEnd() + "\n" + themeBlock + "\n";
|
|
120
|
+
changes.push({
|
|
121
|
+
filePath: cssPath,
|
|
122
|
+
kind: "tailwind-config-updated",
|
|
123
|
+
description: `Appended Tailwind v4 @theme block with "${vibe.meta.id}" vibe tokens`,
|
|
124
|
+
reversible: true,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (!dryRun) {
|
|
128
|
+
fs.writeFileSync(cssPath, newContent, "utf-8");
|
|
129
|
+
}
|
|
130
|
+
return changes;
|
|
131
|
+
}
|
|
132
|
+
// ─── Tailwind v3 — Config File Rewrite ───────────────────────────────────────
|
|
133
|
+
const V3_AGENT_COMMENT = "// paintoliver:generated";
|
|
134
|
+
/**
|
|
135
|
+
* Generate a Tailwind v3 theme.extend object literal string.
|
|
136
|
+
* This is inserted into the tailwind.config.js file.
|
|
137
|
+
*/
|
|
138
|
+
export function generateTailwindV3ThemeExtend(vibe) {
|
|
139
|
+
const indent = " "; // 6 spaces — inside theme.extend: {}
|
|
140
|
+
const lines = [
|
|
141
|
+
`${V3_AGENT_COMMENT}`,
|
|
142
|
+
`colors: {`,
|
|
143
|
+
`${indent} background: "${vibe.colors.background}",`,
|
|
144
|
+
`${indent} foreground: "${vibe.colors.foreground}",`,
|
|
145
|
+
`${indent} primary: {`,
|
|
146
|
+
`${indent} DEFAULT: "${vibe.colors.primary}",`,
|
|
147
|
+
`${indent} foreground: "${vibe.colors.primaryForeground}",`,
|
|
148
|
+
`${indent} },`,
|
|
149
|
+
`${indent} secondary: {`,
|
|
150
|
+
`${indent} DEFAULT: "${vibe.colors.secondary}",`,
|
|
151
|
+
`${indent} foreground: "${vibe.colors.secondaryForeground}",`,
|
|
152
|
+
`${indent} },`,
|
|
153
|
+
`${indent} card: {`,
|
|
154
|
+
`${indent} DEFAULT: "${vibe.colors.card}",`,
|
|
155
|
+
`${indent} foreground: "${vibe.colors.cardForeground}",`,
|
|
156
|
+
`${indent} },`,
|
|
157
|
+
`${indent} muted: {`,
|
|
158
|
+
`${indent} DEFAULT: "${vibe.colors.muted}",`,
|
|
159
|
+
`${indent} foreground: "${vibe.colors.mutedForeground}",`,
|
|
160
|
+
`${indent} },`,
|
|
161
|
+
`${indent} accent: {`,
|
|
162
|
+
`${indent} DEFAULT: "${vibe.colors.accent}",`,
|
|
163
|
+
`${indent} foreground: "${vibe.colors.accentForeground}",`,
|
|
164
|
+
`${indent} },`,
|
|
165
|
+
`${indent} destructive: {`,
|
|
166
|
+
`${indent} DEFAULT: "${vibe.colors.destructive}",`,
|
|
167
|
+
`${indent} foreground: "${vibe.colors.destructiveForeground}",`,
|
|
168
|
+
`${indent} },`,
|
|
169
|
+
`${indent} success: {`,
|
|
170
|
+
`${indent} DEFAULT: "${vibe.colors.success}",`,
|
|
171
|
+
`${indent} foreground: "${vibe.colors.successForeground}",`,
|
|
172
|
+
`${indent} },`,
|
|
173
|
+
`${indent} warning: {`,
|
|
174
|
+
`${indent} DEFAULT: "${vibe.colors.warning}",`,
|
|
175
|
+
`${indent} foreground: "${vibe.colors.warningForeground}",`,
|
|
176
|
+
`${indent} },`,
|
|
177
|
+
`${indent} border: "${vibe.colors.border}",`,
|
|
178
|
+
`${indent} input: "${vibe.colors.input}",`,
|
|
179
|
+
`${indent} ring: "${vibe.colors.ring}",`,
|
|
180
|
+
`${indent} popover: {`,
|
|
181
|
+
`${indent} DEFAULT: "${vibe.colors.popover}",`,
|
|
182
|
+
`${indent} foreground: "${vibe.colors.popoverForeground}",`,
|
|
183
|
+
`${indent} },`,
|
|
184
|
+
`},`,
|
|
185
|
+
`${indent}fontFamily: {`,
|
|
186
|
+
`${indent} sans: ["${vibe.typography.fontFamily.split(",")[0].replace(/'/g, "").trim()}", "sans-serif"],`,
|
|
187
|
+
`${indent} mono: ["${vibe.typography.fontFamilyMono.split(",")[0].replace(/'/g, "").trim()}", "monospace"],`,
|
|
188
|
+
`},`,
|
|
189
|
+
`${indent}borderRadius: {`,
|
|
190
|
+
`${indent} none: "${vibe.radius.none}",`,
|
|
191
|
+
`${indent} sm: "${vibe.radius.sm}",`,
|
|
192
|
+
`${indent} DEFAULT: "${vibe.radius.base}",`,
|
|
193
|
+
`${indent} md: "${vibe.radius.md}",`,
|
|
194
|
+
`${indent} lg: "${vibe.radius.lg}",`,
|
|
195
|
+
`${indent} xl: "${vibe.radius.xl}",`,
|
|
196
|
+
`${indent} "2xl": "${vibe.radius["2xl"]}",`,
|
|
197
|
+
`${indent} "3xl": "${vibe.radius["3xl"]}",`,
|
|
198
|
+
`${indent} full: "${vibe.radius.full}",`,
|
|
199
|
+
`},`,
|
|
200
|
+
`${indent}boxShadow: {`,
|
|
201
|
+
`${indent} sm: "${vibe.shadows.sm}",`,
|
|
202
|
+
`${indent} DEFAULT: "${vibe.shadows.base}",`,
|
|
203
|
+
`${indent} md: "${vibe.shadows.md}",`,
|
|
204
|
+
`${indent} lg: "${vibe.shadows.lg}",`,
|
|
205
|
+
`${indent} xl: "${vibe.shadows.xl}",`,
|
|
206
|
+
`${indent} "2xl": "${vibe.shadows["2xl"]}",`,
|
|
207
|
+
`${indent} inner: "${vibe.shadows.inner}",`,
|
|
208
|
+
`},`,
|
|
209
|
+
];
|
|
210
|
+
return lines.map((l) => (l.startsWith(V3_AGENT_COMMENT) ? l : `${indent}${l}`)).join("\n");
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Apply vibe tokens to a Tailwind v3 config file.
|
|
214
|
+
* Strategy: find the theme.extend block and inject/replace agent-generated content.
|
|
215
|
+
*/
|
|
216
|
+
export function applyTailwindV3Config(configPath, vibe, dryRun) {
|
|
217
|
+
const changes = [];
|
|
218
|
+
let content;
|
|
219
|
+
try {
|
|
220
|
+
content = fs.readFileSync(configPath, "utf-8");
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return changes;
|
|
224
|
+
}
|
|
225
|
+
// If there's already an agent-generated block, replace it
|
|
226
|
+
const existingStart = content.indexOf(V3_AGENT_COMMENT);
|
|
227
|
+
if (existingStart !== -1) {
|
|
228
|
+
// Find the end of the block (next top-level closing brace sequence)
|
|
229
|
+
// This is a conservative approach — we mark our blocks clearly
|
|
230
|
+
const newContent = replaceAgentBlock(content, generateTailwindV3ThemeExtend(vibe));
|
|
231
|
+
if (!dryRun) {
|
|
232
|
+
fs.writeFileSync(configPath, newContent, "utf-8");
|
|
233
|
+
}
|
|
234
|
+
changes.push({
|
|
235
|
+
filePath: configPath,
|
|
236
|
+
kind: "tailwind-config-updated",
|
|
237
|
+
description: `Updated Tailwind v3 theme.extend with "${vibe.meta.id}" vibe tokens`,
|
|
238
|
+
reversible: true,
|
|
239
|
+
});
|
|
240
|
+
return changes;
|
|
241
|
+
}
|
|
242
|
+
// Find theme.extend: { and inject after it
|
|
243
|
+
const themeExtendMatch = content.match(/theme\s*:\s*\{[^}]*extend\s*:\s*\{/s);
|
|
244
|
+
if (themeExtendMatch) {
|
|
245
|
+
const insertIdx = content.indexOf("extend", content.indexOf("theme")) +
|
|
246
|
+
"extend".length +
|
|
247
|
+
content.slice(content.indexOf("extend", content.indexOf("theme")) + "extend".length).indexOf("{") +
|
|
248
|
+
1;
|
|
249
|
+
const newContent = content.slice(0, insertIdx) +
|
|
250
|
+
"\n" +
|
|
251
|
+
generateTailwindV3ThemeExtend(vibe) +
|
|
252
|
+
"\n" +
|
|
253
|
+
content.slice(insertIdx);
|
|
254
|
+
if (!dryRun) {
|
|
255
|
+
fs.writeFileSync(configPath, newContent, "utf-8");
|
|
256
|
+
}
|
|
257
|
+
changes.push({
|
|
258
|
+
filePath: configPath,
|
|
259
|
+
kind: "tailwind-config-updated",
|
|
260
|
+
description: `Injected "${vibe.meta.id}" vibe tokens into Tailwind v3 theme.extend`,
|
|
261
|
+
reversible: true,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
// No theme.extend found — add a warning change record and skip
|
|
266
|
+
changes.push({
|
|
267
|
+
filePath: configPath,
|
|
268
|
+
kind: "skipped",
|
|
269
|
+
description: "Could not locate theme.extend in Tailwind config. Manual update required.",
|
|
270
|
+
reversible: false,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return changes;
|
|
274
|
+
}
|
|
275
|
+
function replaceAgentBlock(content, newBlock) {
|
|
276
|
+
const startIdx = content.indexOf(V3_AGENT_COMMENT);
|
|
277
|
+
if (startIdx === -1)
|
|
278
|
+
return content;
|
|
279
|
+
// Find the end — we look for the next occurrence of }, that isn't inside the block
|
|
280
|
+
// Simple heuristic: find the next line that starts with the base indent level
|
|
281
|
+
const lines = content.split("\n");
|
|
282
|
+
const startLine = content.slice(0, startIdx).split("\n").length - 1;
|
|
283
|
+
// Find end by brace counting after the start marker
|
|
284
|
+
let depth = 0;
|
|
285
|
+
let endLine = startLine;
|
|
286
|
+
let foundFirstBrace = false;
|
|
287
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
288
|
+
for (const ch of lines[i]) {
|
|
289
|
+
if (ch === "{") {
|
|
290
|
+
depth++;
|
|
291
|
+
foundFirstBrace = true;
|
|
292
|
+
}
|
|
293
|
+
else if (ch === "}") {
|
|
294
|
+
depth--;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (foundFirstBrace && depth === 0) {
|
|
298
|
+
endLine = i;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const before = lines.slice(0, startLine).join("\n");
|
|
303
|
+
const after = lines.slice(endLine + 1).join("\n");
|
|
304
|
+
return before + "\n" + newBlock + "\n" + after;
|
|
305
|
+
}
|
|
306
|
+
// ─── Font Import Injection ────────────────────────────────────────────────────
|
|
307
|
+
/**
|
|
308
|
+
* Inject a Google Fonts @import for the vibe's fonts at the top of a CSS file.
|
|
309
|
+
* Only injects if the font family looks like a Google Font (not a system font).
|
|
310
|
+
*/
|
|
311
|
+
export function injectFontImport(cssPath, vibe, dryRun) {
|
|
312
|
+
const changes = [];
|
|
313
|
+
const fontsToImport = new Set();
|
|
314
|
+
const systemFonts = new Set([
|
|
315
|
+
"Arial", "Helvetica", "Verdana", "Georgia", "Times New Roman", "Courier New",
|
|
316
|
+
"Courier", "Lucida Console", "Tahoma", "Trebuchet MS", "Impact", "Comic Sans MS",
|
|
317
|
+
"-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "sans-serif",
|
|
318
|
+
"serif", "monospace", "system-ui", "ui-sans-serif", "ui-serif", "ui-monospace",
|
|
319
|
+
"Arial Black", "Arial Bold", "SF Pro Display", "SF Mono",
|
|
320
|
+
]);
|
|
321
|
+
const extractFontName = (fontStack) => {
|
|
322
|
+
const first = fontStack.split(",")[0].trim().replace(/['"]/g, "");
|
|
323
|
+
if (systemFonts.has(first))
|
|
324
|
+
return null;
|
|
325
|
+
return first;
|
|
326
|
+
};
|
|
327
|
+
const bodyFont = extractFontName(vibe.typography.fontFamily);
|
|
328
|
+
if (bodyFont)
|
|
329
|
+
fontsToImport.add(bodyFont);
|
|
330
|
+
if (vibe.typography.fontFamilyHeading) {
|
|
331
|
+
const headingFont = extractFontName(vibe.typography.fontFamilyHeading);
|
|
332
|
+
if (headingFont && headingFont !== bodyFont)
|
|
333
|
+
fontsToImport.add(headingFont);
|
|
334
|
+
}
|
|
335
|
+
const monoFont = extractFontName(vibe.typography.fontFamilyMono);
|
|
336
|
+
if (monoFont)
|
|
337
|
+
fontsToImport.add(monoFont);
|
|
338
|
+
if (fontsToImport.size === 0)
|
|
339
|
+
return changes;
|
|
340
|
+
const families = Array.from(fontsToImport)
|
|
341
|
+
.map((f) => `family=${encodeURIComponent(f)}:wght@300;400;500;600;700;900`)
|
|
342
|
+
.join("&");
|
|
343
|
+
const importUrl = `https://fonts.googleapis.com/css2?${families}&display=swap`;
|
|
344
|
+
const importLine = `@import url('${importUrl}');`;
|
|
345
|
+
let content;
|
|
346
|
+
try {
|
|
347
|
+
content = fs.readFileSync(cssPath, "utf-8");
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
return changes;
|
|
351
|
+
}
|
|
352
|
+
// Don't add if already present
|
|
353
|
+
if (content.includes("fonts.googleapis.com")) {
|
|
354
|
+
changes.push({
|
|
355
|
+
filePath: cssPath,
|
|
356
|
+
kind: "skipped",
|
|
357
|
+
description: "Google Fonts import already present — skipping font injection",
|
|
358
|
+
reversible: false,
|
|
359
|
+
});
|
|
360
|
+
return changes;
|
|
361
|
+
}
|
|
362
|
+
const newContent = importLine + "\n\n" + content;
|
|
363
|
+
if (!dryRun) {
|
|
364
|
+
fs.writeFileSync(cssPath, newContent, "utf-8");
|
|
365
|
+
}
|
|
366
|
+
changes.push({
|
|
367
|
+
filePath: cssPath,
|
|
368
|
+
kind: "font-import-added",
|
|
369
|
+
description: `Added Google Fonts import for: ${Array.from(fontsToImport).join(", ")}`,
|
|
370
|
+
after: importLine,
|
|
371
|
+
reversible: true,
|
|
372
|
+
});
|
|
373
|
+
return changes;
|
|
374
|
+
}
|
|
375
|
+
// ─── Public Entry Point ───────────────────────────────────────────────────────
|
|
376
|
+
/**
|
|
377
|
+
* Apply Tailwind-specific transformations based on the detected version.
|
|
378
|
+
*/
|
|
379
|
+
export function applyTailwindTransform(stylingSystem, tailwindConfigPath, cssEntryPoints, vibe, dryRun, injectFonts) {
|
|
380
|
+
const changes = [];
|
|
381
|
+
if (stylingSystem === "tailwind-v4") {
|
|
382
|
+
// v4: inject @theme block into the main CSS entry point
|
|
383
|
+
const primaryCSS = cssEntryPoints[0];
|
|
384
|
+
if (primaryCSS) {
|
|
385
|
+
changes.push(...applyTailwindV4Theme(primaryCSS, vibe, dryRun));
|
|
386
|
+
if (injectFonts) {
|
|
387
|
+
changes.push(...injectFontImport(primaryCSS, vibe, dryRun));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
else if (stylingSystem === "tailwind-v3" && tailwindConfigPath) {
|
|
392
|
+
// v3: inject into tailwind.config.js
|
|
393
|
+
changes.push(...applyTailwindV3Config(tailwindConfigPath, vibe, dryRun));
|
|
394
|
+
// Also inject font into the first CSS entry point
|
|
395
|
+
const primaryCSS = cssEntryPoints[0];
|
|
396
|
+
if (primaryCSS && injectFonts) {
|
|
397
|
+
changes.push(...injectFontImport(primaryCSS, vibe, dryRun));
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return changes;
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=tailwind-transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tailwind-transformer.js","sourceRoot":"","sources":["../../src/transformer/tailwind-transformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup Utility
|
|
3
|
+
*
|
|
4
|
+
* Creates a timestamped backup of all files that will be modified
|
|
5
|
+
* before the transformation runs. The backup is placed in a
|
|
6
|
+
* .paintoliver-backup/ directory at the project root.
|
|
7
|
+
*
|
|
8
|
+
* Safety rules:
|
|
9
|
+
* - Backups are always created before any writes
|
|
10
|
+
* - Each run gets its own timestamped directory
|
|
11
|
+
* - Backups can be restored manually or via the `restore` CLI command
|
|
12
|
+
*/
|
|
13
|
+
import type { DetectedFile } from "../vibes/types.js";
|
|
14
|
+
export declare function createBackup(projectRoot: string, files: DetectedFile[]): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* List available backups for a project (newest first).
|
|
17
|
+
*/
|
|
18
|
+
export declare function listBackups(projectRoot: string): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Read the manifest for a specific backup.
|
|
21
|
+
*/
|
|
22
|
+
export interface BackupManifest {
|
|
23
|
+
createdAt: string;
|
|
24
|
+
projectRoot: string;
|
|
25
|
+
files: string[];
|
|
26
|
+
}
|
|
27
|
+
export declare function readBackupManifest(projectRoot: string, backupId: string): BackupManifest | null;
|
|
28
|
+
/**
|
|
29
|
+
* Format a backup ID into a human-readable age string.
|
|
30
|
+
*
|
|
31
|
+
* Backup IDs use the format: 2026‑04‑08T12‑00‑00 (U+2011 non-breaking hyphens
|
|
32
|
+
* replace colons in the time portion to keep the name filesystem-safe).
|
|
33
|
+
* This function normalises the ID back to a parseable ISO string before
|
|
34
|
+
* computing the age.
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatAge(backupId: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Restore files from a specific backup.
|
|
39
|
+
*/
|
|
40
|
+
export declare function restoreBackup(projectRoot: string, backupTimestamp: string): void;
|
|
41
|
+
//# sourceMappingURL=backup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/utils/backup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,EAAE,GACpB,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAYzD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,cAAc,GAAG,IAAI,CAOvB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,CAyBhF"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup Utility
|
|
3
|
+
*
|
|
4
|
+
* Creates a timestamped backup of all files that will be modified
|
|
5
|
+
* before the transformation runs. The backup is placed in a
|
|
6
|
+
* .paintoliver-backup/ directory at the project root.
|
|
7
|
+
*
|
|
8
|
+
* Safety rules:
|
|
9
|
+
* - Backups are always created before any writes
|
|
10
|
+
* - Each run gets its own timestamped directory
|
|
11
|
+
* - Backups can be restored manually or via the `restore` CLI command
|
|
12
|
+
*/
|
|
13
|
+
import fs from "fs";
|
|
14
|
+
import path from "path";
|
|
15
|
+
const BACKUP_DIR_NAME = ".paintoliver-backup";
|
|
16
|
+
export async function createBackup(projectRoot, files) {
|
|
17
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
18
|
+
const backupDir = path.join(projectRoot, BACKUP_DIR_NAME, timestamp);
|
|
19
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
20
|
+
// Only backup files that are CSS/config — we don't touch component files directly
|
|
21
|
+
const backupTargets = files.filter((f) => f.type === "css" ||
|
|
22
|
+
f.type === "scss" ||
|
|
23
|
+
f.type === "sass" ||
|
|
24
|
+
f.type === "tailwind-config");
|
|
25
|
+
for (const file of backupTargets) {
|
|
26
|
+
const relPath = file.relativePath;
|
|
27
|
+
const destPath = path.join(backupDir, relPath);
|
|
28
|
+
const destDir = path.dirname(destPath);
|
|
29
|
+
if (!fs.existsSync(destDir)) {
|
|
30
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
fs.copyFileSync(file.path, destPath);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// If a file can't be backed up, continue — don't abort the whole run
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Write a manifest
|
|
40
|
+
const manifest = {
|
|
41
|
+
createdAt: new Date().toISOString(),
|
|
42
|
+
projectRoot,
|
|
43
|
+
files: backupTargets.map((f) => f.relativePath),
|
|
44
|
+
};
|
|
45
|
+
fs.writeFileSync(path.join(backupDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
|
|
46
|
+
return backupDir;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* List available backups for a project (newest first).
|
|
50
|
+
*/
|
|
51
|
+
export function listBackups(projectRoot) {
|
|
52
|
+
const backupRoot = path.join(projectRoot, BACKUP_DIR_NAME);
|
|
53
|
+
if (!fs.existsSync(backupRoot))
|
|
54
|
+
return [];
|
|
55
|
+
return fs
|
|
56
|
+
.readdirSync(backupRoot)
|
|
57
|
+
.filter((d) => {
|
|
58
|
+
const full = path.join(backupRoot, d);
|
|
59
|
+
return fs.statSync(full).isDirectory() && fs.existsSync(path.join(full, "manifest.json"));
|
|
60
|
+
})
|
|
61
|
+
.sort()
|
|
62
|
+
.reverse(); // newest first
|
|
63
|
+
}
|
|
64
|
+
export function readBackupManifest(projectRoot, backupId) {
|
|
65
|
+
const manifestPath = path.join(projectRoot, BACKUP_DIR_NAME, backupId, "manifest.json");
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Format a backup ID into a human-readable age string.
|
|
75
|
+
*
|
|
76
|
+
* Backup IDs use the format: 2026‑04‑08T12‑00‑00 (U+2011 non-breaking hyphens
|
|
77
|
+
* replace colons in the time portion to keep the name filesystem-safe).
|
|
78
|
+
* This function normalises the ID back to a parseable ISO string before
|
|
79
|
+
* computing the age.
|
|
80
|
+
*/
|
|
81
|
+
export function formatAge(backupId) {
|
|
82
|
+
try {
|
|
83
|
+
// Backup IDs use U+2011 (non-breaking hyphen) in place of colons.
|
|
84
|
+
// Replace them and append Z so Date can parse it as UTC.
|
|
85
|
+
const normalized = String(backupId).replace(/\u2011/g, ":") + "Z";
|
|
86
|
+
const ts = new Date(normalized);
|
|
87
|
+
if (isNaN(ts.getTime()))
|
|
88
|
+
return backupId;
|
|
89
|
+
const diffMs = Date.now() - ts.getTime();
|
|
90
|
+
const diffSecs = Math.floor(diffMs / 1000);
|
|
91
|
+
if (diffSecs < 60)
|
|
92
|
+
return `${diffSecs}s ago`;
|
|
93
|
+
if (diffSecs < 3600)
|
|
94
|
+
return `${Math.floor(diffSecs / 60)}m ago`;
|
|
95
|
+
if (diffSecs < 86400)
|
|
96
|
+
return `${Math.floor(diffSecs / 3600)}h ago`;
|
|
97
|
+
return `${Math.floor(diffSecs / 86400)}d ago`;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return backupId;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Restore files from a specific backup.
|
|
105
|
+
*/
|
|
106
|
+
export function restoreBackup(projectRoot, backupTimestamp) {
|
|
107
|
+
const backupDir = path.join(projectRoot, BACKUP_DIR_NAME, backupTimestamp);
|
|
108
|
+
if (!fs.existsSync(backupDir)) {
|
|
109
|
+
throw new Error(`Backup not found: ${backupDir}`);
|
|
110
|
+
}
|
|
111
|
+
const manifestPath = path.join(backupDir, "manifest.json");
|
|
112
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
113
|
+
for (const relPath of manifest.files) {
|
|
114
|
+
const src = path.join(backupDir, relPath);
|
|
115
|
+
const dest = path.join(projectRoot, relPath);
|
|
116
|
+
if (!fs.existsSync(src))
|
|
117
|
+
continue;
|
|
118
|
+
const destDir = path.dirname(dest);
|
|
119
|
+
if (!fs.existsSync(destDir)) {
|
|
120
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
121
|
+
}
|
|
122
|
+
fs.copyFileSync(src, dest);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/utils/backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Vibe } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Brutalist Vibe — "Industrial Integrity"
|
|
4
|
+
*
|
|
5
|
+
* Source: brutalist-light.json / brutalist-dark.json
|
|
6
|
+
* Mechanical clarity, structural honesty, visible architecture.
|
|
7
|
+
* Hard-offset shadows. No border radius anywhere. Heavy typography.
|
|
8
|
+
* Success/info collapse to primary (black/white). Brutalism rejects semantic hue.
|
|
9
|
+
*/
|
|
10
|
+
export declare const brutalist: Vibe;
|
|
11
|
+
//# sourceMappingURL=brutalist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brutalist.d.ts","sourceRoot":"","sources":["../../../src/vibes/definitions/brutalist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,IAsNvB,CAAC"}
|