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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +207 -0
  3. package/dist/analyzer/index.d.ts +20 -0
  4. package/dist/analyzer/index.d.ts.map +1 -0
  5. package/dist/analyzer/index.js +387 -0
  6. package/dist/analyzer/index.js.map +1 -0
  7. package/dist/cli.d.ts +26 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +436 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/contrast/index.d.ts +88 -0
  12. package/dist/contrast/index.d.ts.map +1 -0
  13. package/dist/contrast/index.js +314 -0
  14. package/dist/contrast/index.js.map +1 -0
  15. package/dist/paintoliver.bundle.js +14530 -0
  16. package/dist/reporter/index.d.ts +43 -0
  17. package/dist/reporter/index.d.ts.map +1 -0
  18. package/dist/reporter/index.js +235 -0
  19. package/dist/reporter/index.js.map +1 -0
  20. package/dist/transformer/css-var-transformer.d.ts +46 -0
  21. package/dist/transformer/css-var-transformer.d.ts.map +1 -0
  22. package/dist/transformer/css-var-transformer.js +422 -0
  23. package/dist/transformer/css-var-transformer.js.map +1 -0
  24. package/dist/transformer/index.d.ts +17 -0
  25. package/dist/transformer/index.d.ts.map +1 -0
  26. package/dist/transformer/index.js +213 -0
  27. package/dist/transformer/index.js.map +1 -0
  28. package/dist/transformer/tailwind-transformer.d.ts +47 -0
  29. package/dist/transformer/tailwind-transformer.d.ts.map +1 -0
  30. package/dist/transformer/tailwind-transformer.js +402 -0
  31. package/dist/transformer/tailwind-transformer.js.map +1 -0
  32. package/dist/utils/backup.d.ts +41 -0
  33. package/dist/utils/backup.d.ts.map +1 -0
  34. package/dist/utils/backup.js +125 -0
  35. package/dist/utils/backup.js.map +1 -0
  36. package/dist/vibes/definitions/brutalist.d.ts +11 -0
  37. package/dist/vibes/definitions/brutalist.d.ts.map +1 -0
  38. package/dist/vibes/definitions/brutalist.js +203 -0
  39. package/dist/vibes/definitions/brutalist.js.map +1 -0
  40. package/dist/vibes/definitions/corporate.d.ts +12 -0
  41. package/dist/vibes/definitions/corporate.d.ts.map +1 -0
  42. package/dist/vibes/definitions/corporate.js +212 -0
  43. package/dist/vibes/definitions/corporate.js.map +1 -0
  44. package/dist/vibes/definitions/glassmorphism.d.ts +20 -0
  45. package/dist/vibes/definitions/glassmorphism.d.ts.map +1 -0
  46. package/dist/vibes/definitions/glassmorphism.js +217 -0
  47. package/dist/vibes/definitions/glassmorphism.js.map +1 -0
  48. package/dist/vibes/definitions/kinetic-terminal.d.ts +20 -0
  49. package/dist/vibes/definitions/kinetic-terminal.d.ts.map +1 -0
  50. package/dist/vibes/definitions/kinetic-terminal.js +242 -0
  51. package/dist/vibes/definitions/kinetic-terminal.js.map +1 -0
  52. package/dist/vibes/definitions/minimal.d.ts +11 -0
  53. package/dist/vibes/definitions/minimal.d.ts.map +1 -0
  54. package/dist/vibes/definitions/minimal.js +167 -0
  55. package/dist/vibes/definitions/minimal.js.map +1 -0
  56. package/dist/vibes/definitions/windows-xp.d.ts +12 -0
  57. package/dist/vibes/definitions/windows-xp.d.ts.map +1 -0
  58. package/dist/vibes/definitions/windows-xp.js +229 -0
  59. package/dist/vibes/definitions/windows-xp.js.map +1 -0
  60. package/dist/vibes/registry.d.ts +25 -0
  61. package/dist/vibes/registry.d.ts.map +1 -0
  62. package/dist/vibes/registry.js +52 -0
  63. package/dist/vibes/registry.js.map +1 -0
  64. package/dist/vibes/types.d.ts +428 -0
  65. package/dist/vibes/types.d.ts.map +1 -0
  66. package/dist/vibes/types.js +12 -0
  67. package/dist/vibes/types.js.map +1 -0
  68. package/package.json +41 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sakshya Sharma
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,207 @@
1
+ # FrontEnd Agent
2
+
3
+ > Apply consistent visual vibes to front-end codebases — safely, predictably, and in seconds.
4
+
5
+ FrontEnd Agent transforms the visual styling of an existing project to match a selected design "vibe" — without touching business logic, component structure, or application behavior.
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g paintoliver
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # See what's available
21
+ paintoliver list
22
+
23
+ # Preview changes without writing anything (always a good first step)
24
+ paintoliver apply minimal ./your-project --dry-run
25
+
26
+ # Apply a vibe
27
+ paintoliver apply kinetic-terminal ./your-project
28
+
29
+ # Didn't like it? Restore the backup that was created automatically
30
+ paintoliver restore ./your-project
31
+ ```
32
+
33
+ ---
34
+
35
+ ## What is a Vibe?
36
+
37
+ A vibe is a fully portable definition of a visual language: colors, typography, spacing, border radius, shadows, and motion — structured as data, not instructions. Every vibe ships with both light and dark mode variants. The same vibe applied to the same project always produces the same result.
38
+
39
+ **Built-in vibes:**
40
+
41
+ | Vibe | Character | Base mode |
42
+ |---|---|---|
43
+ | `kinetic-terminal` | High-contrast cyberpunk. Cyan/magenta on near-black. Neon glow. | Dark |
44
+ | `minimal` | Maximum whitespace. Barely-there borders. Swiss typography. | Light |
45
+ | `brutalist` | Black borders. Heavy type. Zero decoration. Raw structure. | Light |
46
+ | `corporate` | Electric blue. Precise grid. Trustworthy and legible. | Light |
47
+ | `glassmorphism` | Frosted glass surfaces. Violet gradients. Translucent layers. | Dark |
48
+ | `windows-xp` | Skeuomorphic chrome. Gradients and bevels. Warm cream surfaces. | Light |
49
+
50
+ ---
51
+
52
+ ## Commands
53
+
54
+ ### `apply`
55
+
56
+ ```bash
57
+ paintoliver apply <vibe> [path]
58
+ paintoliver apply [path] # prompts for vibe if omitted
59
+ ```
60
+
61
+ | Flag | Default | Description |
62
+ |---|---|---|
63
+ | `--dry-run` | off | Preview all changes without writing any files |
64
+ | `--backup` | on | Create a timestamped backup before modifying |
65
+ | `--no-backup` | — | Skip backup creation |
66
+ | `--watch` | off | Re-apply automatically when CSS files change |
67
+ | `--fix-contrast` | off | Auto-fix any WCAG AA contrast failures |
68
+ | `--no-contrast` | off | Skip contrast checking entirely |
69
+ | `--fonts` | off | Inject a Google Fonts `@import` for the vibe's typefaces |
70
+ | `--verbose` | off | Show before/after values for every change |
71
+ | `--report <path>` | — | Write a machine-readable JSON report |
72
+
73
+ ### `analyze`
74
+
75
+ ```bash
76
+ paintoliver analyze [path]
77
+ paintoliver analyze [path] --json
78
+ ```
79
+
80
+ Scans a project and reports its styling system, detected CSS variables, entry points, and theme mode. Read-only — no files are modified.
81
+
82
+ ### `list`
83
+
84
+ ```bash
85
+ paintoliver list
86
+ ```
87
+
88
+ Lists all available vibes with descriptions and tags.
89
+
90
+ ### `list-backups`
91
+
92
+ ```bash
93
+ paintoliver list-backups [path]
94
+ ```
95
+
96
+ Shows all backups for a project with timestamps and ages.
97
+
98
+ ### `restore`
99
+
100
+ ```bash
101
+ paintoliver restore [path]
102
+ paintoliver restore [path] --backup-id 2026-04-08T12-00-00
103
+ ```
104
+
105
+ Restores files from the most recent backup, or a specific one by ID.
106
+
107
+ ### `clear-overrides`
108
+
109
+ ```bash
110
+ paintoliver clear-overrides [path]
111
+ ```
112
+
113
+ Removes any persisted contrast overrides from `.paintoliver.json`, reverting to the vibe's original colors on the next apply.
114
+
115
+ ---
116
+
117
+ ## How It Works
118
+
119
+ ### 1. Analyze
120
+ Scans the project to detect the styling system (Tailwind v3/v4, CSS modules, SCSS, plain CSS), find CSS entry points, extract custom property names, and detect the project's theme mode.
121
+
122
+ ### 2. Backup
123
+ Copies every file that will be modified into `.paintoliver-backup/<timestamp>/` before any writes happen.
124
+
125
+ ### 3. Transform
126
+ - **Tailwind projects** — updates `tailwind.config.js` color/font/radius sections or injects a `@theme` block (v4)
127
+ - **CSS/SCSS files** — rewrites custom property values that map to semantic vibe tokens, correctly handling separate dark-mode and light-mode selector blocks
128
+ - **Token-less projects** — injects a complete token block into the primary CSS entry point, including base, `@media (prefers-color-scheme)`, and `.dark/.light` class selector blocks
129
+
130
+ ### 4. Contrast check
131
+ After transformation, runs WCAG 2.2 AA checks on the applied palette (4.5:1 for text, 3.0:1 for UI components). Failures can be auto-fixed or reviewed interactively. Fixes are saved to `.paintoliver.json` and reapplied on every subsequent run.
132
+
133
+ ### 5. Report
134
+ Every change is printed with a confidence indicator. Low-confidence rewrites are flagged for review. A full JSON report can be written for code review.
135
+
136
+ ---
137
+
138
+ ## Safety
139
+
140
+ - **Backups by default** — a timestamped copy of all modified files is saved before any writes
141
+ - **Dry run mode** — preview every change before it happens
142
+ - **Confidence scoring** — CSS variables that can't be confidently mapped to a semantic token are left untouched
143
+ - **No deletions** — no files, variables, or classes are ever removed
144
+ - **Fails safely** — files that can't be processed confidently are skipped and reported, not errored
145
+
146
+ ---
147
+
148
+ ## Dark and Light Mode
149
+
150
+ Every vibe defines a base mode and an override for the opposite mode. When a token block is injected into a project, three blocks are written:
151
+
152
+ ```css
153
+ /* Base (default mode) */
154
+ :root { --primary: #00F0FF; ... }
155
+
156
+ /* System preference */
157
+ @media (prefers-color-scheme: light) {
158
+ :root:not(.dark):not([data-theme="dark"]) { --primary: #008A96; ... }
159
+ }
160
+
161
+ /* Explicit class (Next.js next-themes, Tailwind darkMode: 'class', etc.) */
162
+ .light, [data-theme="light"] { --primary: #008A96; ... }
163
+ ```
164
+
165
+ Only tokens that differ between modes are listed in the override blocks — everything else inherits from `:root`.
166
+
167
+ ---
168
+
169
+ ## Watch Mode
170
+
171
+ ```bash
172
+ paintoliver apply kinetic-terminal ./your-app --watch
173
+ ```
174
+
175
+ Watches for changes to CSS and config files and re-applies the vibe automatically with a 350ms debounce. Useful during active design iteration. No backup is created on re-applies.
176
+
177
+ ---
178
+
179
+ ## Adding a Custom Vibe
180
+
181
+ 1. Create `src/vibes/definitions/my-vibe.ts` exporting a `Vibe` object
182
+ 2. Add its ID to the `VibeId` union in `src/vibes/types.ts`
183
+ 3. Import and register it in `src/vibes/registry.ts`
184
+
185
+ That's it. The CLI, analyzer, transformer, and reporter pick it up automatically.
186
+
187
+ Refer to any existing vibe in `src/vibes/definitions/` as a template, and `src/vibes/types.ts` for the full interface.
188
+
189
+ ---
190
+
191
+ ## Supported Projects
192
+
193
+ | Stack | Support |
194
+ |---|---|
195
+ | React + Tailwind v4 | Full |
196
+ | React + Tailwind v3 | Full |
197
+ | React + CSS Modules | CSS custom properties |
198
+ | React + plain CSS/SCSS | CSS custom properties |
199
+ | Next.js | Full (same as React above) |
200
+ | Vue / Svelte | CSS-level transforms only |
201
+ | styled-components / Emotion | CSS custom properties only |
202
+
203
+ ---
204
+
205
+ ## Requirements
206
+
207
+ - Node.js ≥ 18
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Project Analyzer
3
+ *
4
+ * Inspects a front-end project directory and produces a ProjectAnalysis:
5
+ * a structured description of what styling system is in use, which files
6
+ * are relevant to visual styling, and what design tokens already exist.
7
+ *
8
+ * The analyzer is conservative — it only reports what it can confirm.
9
+ * If it cannot determine something, it leaves the field as "unknown"
10
+ * rather than guessing.
11
+ */
12
+ import type { ProjectAnalysis } from "../vibes/types.js";
13
+ /**
14
+ * Analyze a project directory and return a structured ProjectAnalysis.
15
+ *
16
+ * This is the entry point for all project inspection work.
17
+ * The analysis is read-only — no files are modified.
18
+ */
19
+ export declare function analyzeProject(rootPath: string, exclude?: string[]): Promise<ProjectAnalysis>;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,mBAAmB,CAAC;AAqZ3B;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAM,EAAO,GACrB,OAAO,CAAC,eAAe,CAAC,CAqC1B"}
@@ -0,0 +1,387 @@
1
+ /**
2
+ * Project Analyzer
3
+ *
4
+ * Inspects a front-end project directory and produces a ProjectAnalysis:
5
+ * a structured description of what styling system is in use, which files
6
+ * are relevant to visual styling, and what design tokens already exist.
7
+ *
8
+ * The analyzer is conservative — it only reports what it can confirm.
9
+ * If it cannot determine something, it leaves the field as "unknown"
10
+ * rather than guessing.
11
+ */
12
+ import fs from "fs";
13
+ import path from "path";
14
+ import { glob } from "fast-glob";
15
+ // ─── Constants ────────────────────────────────────────────────────────────────
16
+ const CSS_CUSTOM_PROP_RE = /--[\w-]+(?=\s*:)/g;
17
+ const TAILWIND_CLASS_TOKENS = /class(?:Name)?=["'`]([^"'`]+)["'`]/g;
18
+ const TAILWIND_CN_CALL = /cn\(([^)]+)\)/g;
19
+ // Files and directories the analyzer should always skip
20
+ const ALWAYS_EXCLUDE = [
21
+ "**/node_modules/**",
22
+ "**/.git/**",
23
+ "**/dist/**",
24
+ "**/build/**",
25
+ "**/.next/**",
26
+ "**/.nuxt/**",
27
+ "**/out/**",
28
+ "**/.cache/**",
29
+ "**/coverage/**",
30
+ "**/*.min.css",
31
+ "**/*.min.js",
32
+ ];
33
+ // ─── Framework Detection ──────────────────────────────────────────────────────
34
+ function detectFramework(rootPath) {
35
+ const pkg = readJsonSafe(path.join(rootPath, "package.json"));
36
+ if (!pkg)
37
+ return "unknown";
38
+ const deps = {
39
+ ...(pkg.dependencies ?? {}),
40
+ ...(pkg.devDependencies ?? {}),
41
+ };
42
+ if ("next" in deps)
43
+ return "next";
44
+ if ("@angular/core" in deps)
45
+ return "angular";
46
+ if ("svelte" in deps)
47
+ return "svelte";
48
+ if ("vue" in deps)
49
+ return "vue";
50
+ if ("react" in deps && "vite" in deps)
51
+ return "vite-react";
52
+ if ("react" in deps)
53
+ return "react";
54
+ // Check for plain HTML (no package.json deps or index.html at root)
55
+ if (fs.existsSync(path.join(rootPath, "index.html")))
56
+ return "plain-html";
57
+ return "unknown";
58
+ }
59
+ // ─── Styling System Detection ─────────────────────────────────────────────────
60
+ function detectStylingSystem(rootPath) {
61
+ const pkg = readJsonSafe(path.join(rootPath, "package.json"));
62
+ const deps = pkg
63
+ ? {
64
+ ...(pkg.dependencies ?? {}),
65
+ ...(pkg.devDependencies ?? {}),
66
+ }
67
+ : {};
68
+ // Check for CSS-in-JS
69
+ if ("@emotion/react" in deps || "@emotion/styled" in deps)
70
+ return { system: "emotion" };
71
+ if ("styled-components" in deps)
72
+ return { system: "styled-components" };
73
+ if ("@vanilla-extract/css" in deps)
74
+ return { system: "vanilla-extract" };
75
+ // Check for Tailwind
76
+ const tailwindVersion = deps["tailwindcss"];
77
+ if (tailwindVersion) {
78
+ const configPath = findTailwindConfig(rootPath);
79
+ const isV4 = tailwindVersion.startsWith("^4") || tailwindVersion.startsWith("4");
80
+ return {
81
+ system: isV4 ? "tailwind-v4" : "tailwind-v3",
82
+ tailwindConfigPath: configPath ?? undefined,
83
+ };
84
+ }
85
+ // Check for SCSS/Sass
86
+ if ("sass" in deps || "node-sass" in deps) {
87
+ return { system: hasSassFiles(rootPath, "scss") ? "scss" : "sass" };
88
+ }
89
+ // CSS Modules — detected by file pattern, not deps
90
+ if (hasCSSModuleFiles(rootPath))
91
+ return { system: "css-modules" };
92
+ // Plain CSS fallback
93
+ return { system: "plain-css" };
94
+ }
95
+ function findTailwindConfig(rootPath) {
96
+ const candidates = [
97
+ "tailwind.config.js",
98
+ "tailwind.config.ts",
99
+ "tailwind.config.mjs",
100
+ "tailwind.config.cjs",
101
+ ];
102
+ for (const c of candidates) {
103
+ const full = path.join(rootPath, c);
104
+ if (fs.existsSync(full))
105
+ return full;
106
+ }
107
+ return null;
108
+ }
109
+ function hasSassFiles(rootPath, ext) {
110
+ try {
111
+ const files = glob.sync(`**/*.${ext}`, {
112
+ cwd: rootPath,
113
+ ignore: ALWAYS_EXCLUDE,
114
+ absolute: false,
115
+ });
116
+ return files.length > 0;
117
+ }
118
+ catch {
119
+ return false;
120
+ }
121
+ }
122
+ function hasCSSModuleFiles(rootPath) {
123
+ try {
124
+ const files = glob.sync("**/*.module.css", {
125
+ cwd: rootPath,
126
+ ignore: ALWAYS_EXCLUDE,
127
+ absolute: false,
128
+ });
129
+ return files.length > 0;
130
+ }
131
+ catch {
132
+ return false;
133
+ }
134
+ }
135
+ // ─── File Discovery ───────────────────────────────────────────────────────────
136
+ async function discoverRelevantFiles(rootPath, exclude) {
137
+ const ignore = [...ALWAYS_EXCLUDE, ...exclude];
138
+ const detectedFiles = [];
139
+ // CSS-family files
140
+ const cssFiles = await glob(["**/*.css", "**/*.scss", "**/*.sass"], {
141
+ cwd: rootPath,
142
+ ignore,
143
+ absolute: true,
144
+ stats: true,
145
+ });
146
+ for (const entry of cssFiles) {
147
+ const filePath = entry.path;
148
+ const relativePath = path.relative(rootPath, filePath);
149
+ const ext = path.extname(filePath).slice(1);
150
+ const isModule = relativePath.includes(".module.");
151
+ const isEntry = relativePath.includes("global") ||
152
+ relativePath.includes("index") ||
153
+ relativePath.includes("main") ||
154
+ relativePath.includes("app") ||
155
+ relativePath.includes("base") ||
156
+ relativePath.includes("reset");
157
+ const content = readFileSafe(filePath);
158
+ const cssCustomProperties = content
159
+ ? Array.from(new Set(content.match(CSS_CUSTOM_PROP_RE) ?? []))
160
+ : [];
161
+ const stat = entry.stats ?? fs.statSync(filePath);
162
+ detectedFiles.push({
163
+ path: filePath,
164
+ relativePath,
165
+ type: isModule ? "css" : ext === "css" ? "css" : ext,
166
+ isEntryPoint: isEntry && !isModule,
167
+ cssCustomProperties,
168
+ sizeBytes: stat.size,
169
+ });
170
+ }
171
+ // Tailwind config files
172
+ const tailwindConfigs = await glob(["tailwind.config.{js,ts,mjs,cjs}", "postcss.config.{js,ts,mjs,cjs}"], { cwd: rootPath, ignore, absolute: true });
173
+ for (const filePath of tailwindConfigs) {
174
+ const stat = fs.statSync(filePath);
175
+ detectedFiles.push({
176
+ path: filePath,
177
+ relativePath: path.relative(rootPath, filePath),
178
+ type: "tailwind-config",
179
+ isEntryPoint: true,
180
+ sizeBytes: stat.size,
181
+ });
182
+ }
183
+ // Component files (React/Vue/Svelte)
184
+ const componentFiles = await glob(["**/*.{tsx,jsx,vue,svelte}", "**/*.{ts,js}"], {
185
+ cwd: rootPath,
186
+ ignore: [
187
+ ...ignore,
188
+ "**/*.test.*",
189
+ "**/*.spec.*",
190
+ "**/*.stories.*",
191
+ "**/*.d.ts",
192
+ "**/vite.config.*",
193
+ "**/next.config.*",
194
+ "**/webpack.config.*",
195
+ ],
196
+ absolute: true,
197
+ stats: true,
198
+ });
199
+ for (const entry of componentFiles) {
200
+ // stats:true returns Entry objects — pull the plain path string out
201
+ const filePath = entry.path;
202
+ const relativePath = path.relative(rootPath, filePath);
203
+ const stat = entry.stats ?? fs.statSync(filePath);
204
+ if (stat.size > 200_000)
205
+ continue;
206
+ const content = readFileSafe(filePath);
207
+ if (!content)
208
+ continue;
209
+ // Only include if it contains className/class references
210
+ const hasStyling = content.includes("className") ||
211
+ content.includes(' class=') ||
212
+ content.includes("styles.") ||
213
+ content.includes("css`") ||
214
+ content.includes("styled.");
215
+ if (!hasStyling)
216
+ continue;
217
+ const tailwindClasses = extractTailwindClasses(content);
218
+ detectedFiles.push({
219
+ path: filePath,
220
+ relativePath,
221
+ type: "component",
222
+ isEntryPoint: false,
223
+ tailwindClasses,
224
+ sizeBytes: stat.size,
225
+ });
226
+ }
227
+ return detectedFiles;
228
+ }
229
+ function extractTailwindClasses(content) {
230
+ const classes = new Set();
231
+ // Match className="..." and class="..."
232
+ let match;
233
+ const classRe = new RegExp(TAILWIND_CLASS_TOKENS.source, "g");
234
+ while ((match = classRe.exec(content)) !== null) {
235
+ const raw = match[1];
236
+ for (const cls of raw.split(/\s+/)) {
237
+ if (cls)
238
+ classes.add(cls);
239
+ }
240
+ }
241
+ // Match cn(...) calls
242
+ const cnRe = new RegExp(TAILWIND_CN_CALL.source, "g");
243
+ while ((match = cnRe.exec(content)) !== null) {
244
+ const raw = match[1];
245
+ // Extract quoted strings inside cn()
246
+ const quoted = raw.match(/"([^"]+)"|'([^']+)'/g) ?? [];
247
+ for (const q of quoted) {
248
+ const inner = q.slice(1, -1);
249
+ for (const cls of inner.split(/\s+/)) {
250
+ if (cls)
251
+ classes.add(cls);
252
+ }
253
+ }
254
+ }
255
+ return Array.from(classes);
256
+ }
257
+ // ─── CSS Entry Point Detection ────────────────────────────────────────────────
258
+ function findCSSEntryPoints(files) {
259
+ return files
260
+ .filter((f) => (f.type === "css" || f.type === "scss" || f.type === "sass") && f.isEntryPoint)
261
+ .map((f) => f.path);
262
+ }
263
+ // ─── CSS Custom Property Aggregation ─────────────────────────────────────────
264
+ function aggregateCSSVars(files) {
265
+ const all = new Set();
266
+ for (const f of files) {
267
+ for (const v of f.cssCustomProperties ?? []) {
268
+ all.add(v);
269
+ }
270
+ }
271
+ return Array.from(all).sort();
272
+ }
273
+ // ─── Theme Mode Detection ─────────────────────────────────────────────────────
274
+ function detectThemeMode(files) {
275
+ let hasLight = false;
276
+ let hasDark = false;
277
+ for (const f of files) {
278
+ if (f.type !== "css" && f.type !== "scss" && f.type !== "sass")
279
+ continue;
280
+ const content = readFileSafe(f.path) ?? "";
281
+ if (content.includes("prefers-color-scheme: dark") || content.includes(".dark ")) {
282
+ hasDark = true;
283
+ }
284
+ if (content.includes("prefers-color-scheme: light") || content.includes(".light ")) {
285
+ hasLight = true;
286
+ }
287
+ }
288
+ if (hasLight && hasDark)
289
+ return "both";
290
+ if (hasDark)
291
+ return "dark";
292
+ return "light";
293
+ }
294
+ // ─── Token File Detection ─────────────────────────────────────────────────────
295
+ function detectTokenFile(files) {
296
+ return files.some((f) => {
297
+ const name = path.basename(f.path).toLowerCase();
298
+ return (name.includes("token") ||
299
+ name.includes("variable") ||
300
+ name.includes("design-system") ||
301
+ name.includes("theme"));
302
+ });
303
+ }
304
+ // ─── Warnings ─────────────────────────────────────────────────────────────────
305
+ function buildWarnings(stylingSystem, framework, files) {
306
+ const warnings = [];
307
+ if (stylingSystem === "styled-components") {
308
+ warnings.push("styled-components detected: CSS-in-JS transforms are limited. " +
309
+ "The agent will update CSS custom properties but cannot rewrite styled() templates.");
310
+ }
311
+ if (stylingSystem === "emotion") {
312
+ warnings.push("Emotion detected: CSS-in-JS transforms are limited. " +
313
+ "The agent will update CSS custom properties where possible.");
314
+ }
315
+ if (stylingSystem === "vanilla-extract") {
316
+ warnings.push("vanilla-extract detected: transforms will target generated CSS output files only.");
317
+ }
318
+ if (framework === "unknown") {
319
+ warnings.push("Framework could not be determined. The agent will operate in generic CSS mode.");
320
+ }
321
+ if (stylingSystem === "unknown") {
322
+ warnings.push("Styling system could not be determined. The agent will scan for CSS files only.");
323
+ }
324
+ const largeFiles = files.filter((f) => f.sizeBytes > 100_000);
325
+ if (largeFiles.length > 0) {
326
+ warnings.push(`${largeFiles.length} large file(s) detected (>100KB). ` +
327
+ "These will be analyzed but changes will be conservative.");
328
+ }
329
+ return warnings;
330
+ }
331
+ // ─── Utilities ─────────────────────────────────────────────────────────────────
332
+ function readFileSafe(filePath) {
333
+ try {
334
+ return fs.readFileSync(filePath, "utf-8");
335
+ }
336
+ catch {
337
+ return null;
338
+ }
339
+ }
340
+ function readJsonSafe(filePath) {
341
+ try {
342
+ return JSON.parse(fs.readFileSync(filePath, "utf-8"));
343
+ }
344
+ catch {
345
+ return null;
346
+ }
347
+ }
348
+ // ─── Public API ───────────────────────────────────────────────────────────────
349
+ /**
350
+ * Analyze a project directory and return a structured ProjectAnalysis.
351
+ *
352
+ * This is the entry point for all project inspection work.
353
+ * The analysis is read-only — no files are modified.
354
+ */
355
+ export async function analyzeProject(rootPath, exclude = []) {
356
+ if (!fs.existsSync(rootPath)) {
357
+ throw new Error(`Project root does not exist: ${rootPath}`);
358
+ }
359
+ const resolvedRoot = path.resolve(rootPath);
360
+ // Parallel detection — these don't depend on each other
361
+ const [framework, stylingDetection] = await Promise.all([
362
+ Promise.resolve(detectFramework(resolvedRoot)),
363
+ Promise.resolve(detectStylingSystem(resolvedRoot)),
364
+ ]);
365
+ const { system: stylingSystem, tailwindConfigPath } = stylingDetection;
366
+ // File discovery — needs styling system to be known first
367
+ const relevantFiles = await discoverRelevantFiles(resolvedRoot, exclude);
368
+ const cssEntryPoints = findCSSEntryPoints(relevantFiles);
369
+ const detectedCSSVars = aggregateCSSVars(relevantFiles);
370
+ const themeMode = detectThemeMode(relevantFiles);
371
+ const hasTokenFile = detectTokenFile(relevantFiles);
372
+ const warnings = buildWarnings(stylingSystem, framework, relevantFiles);
373
+ return {
374
+ rootPath: resolvedRoot,
375
+ framework,
376
+ stylingSystem,
377
+ relevantFiles,
378
+ detectedCSSVars,
379
+ tailwindConfigPath: tailwindConfigPath ?? undefined,
380
+ cssEntryPoints,
381
+ hasTokenFile,
382
+ themeMode,
383
+ warnings,
384
+ analyzedAt: new Date().toISOString(),
385
+ };
386
+ }
387
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"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"}