blotdev 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Blot Studios, LLC
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,74 @@
1
+ # blotdev
2
+
3
+ Scan codebases for brand consistency issues. Catches hardcoded colors, fonts, and styles that should use design tokens.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install blotdev
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ npx blotdev # full scan, outputs brand-issues.md
15
+ npx blotdev --staged # staged files only (for pre-commit)
16
+ ```
17
+
18
+ ## Config
19
+
20
+ Create `blot.config.json` in your project root:
21
+
22
+ ```json
23
+ {
24
+ "colors": ["#1a1a1a", "#ffffff", "#FF6B35"],
25
+ "fonts": ["Inter", "Space Grotesk"],
26
+ "allowInlineStyles": false
27
+ }
28
+ ```
29
+
30
+ | Option | Description |
31
+ |--------|-------------|
32
+ | `colors` | Allowed hex colors |
33
+ | `fonts` | Allowed font families |
34
+ | `allowInlineStyles` | Allow `style={{}}` in JSX |
35
+
36
+ ## Output
37
+
38
+ ```
39
+ Scanned 42 files
40
+
41
+ Colors (2):
42
+ src/components/Button.tsx:14 #3b82f6
43
+ src/components/Card.tsx:8 #ef4444
44
+
45
+ Fonts (1):
46
+ src/styles/globals.css:22 Helvetica
47
+
48
+ 3 issues found.
49
+ ```
50
+
51
+ Full scans also write `brand-issues.md` with a checklist format.
52
+
53
+ ## Pre-commit
54
+
55
+ With lint-staged:
56
+
57
+ ```json
58
+ {
59
+ "lint-staged": {
60
+ "*.{ts,tsx,css,scss}": "blotdev --staged"
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## Options
66
+
67
+ | Flag | Description |
68
+ |------|-------------|
69
+ | `-s, --staged` | Scan staged files only |
70
+ | `-h, --help` | Show help |
71
+
72
+ ## License
73
+
74
+ MIT - [Blot Studios, LLC](https://blot.dev)
@@ -0,0 +1,5 @@
1
+ {
2
+ "colors": ["#1a1a1a", "#ffffff", "#FF6B35"],
3
+ "fonts": ["Inter", "Space Grotesk"],
4
+ "allowInlineStyles": false
5
+ }
@@ -0,0 +1,3 @@
1
+ import { Config } from "./types";
2
+ export declare function loadConfig(cwd?: string): Config;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAQjC,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAqB9D"}
package/dist/config.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const DEFAULT_CONFIG = {
40
+ colors: [],
41
+ fonts: [],
42
+ allowInlineStyles: true,
43
+ };
44
+ function loadConfig(cwd = process.cwd()) {
45
+ const configPath = path.join(cwd, "blot.config.json");
46
+ if (!fs.existsSync(configPath)) {
47
+ console.error("Warning: No blot.config.json found, using defaults");
48
+ return DEFAULT_CONFIG;
49
+ }
50
+ try {
51
+ const raw = fs.readFileSync(configPath, "utf-8");
52
+ const parsed = JSON.parse(raw);
53
+ return {
54
+ colors: Array.isArray(parsed.colors) ? parsed.colors : [],
55
+ fonts: Array.isArray(parsed.fonts) ? parsed.fonts : [],
56
+ allowInlineStyles: parsed.allowInlineStyles ?? true,
57
+ };
58
+ }
59
+ catch {
60
+ console.error("Warning: Failed to parse blot.config.json, using defaults");
61
+ return DEFAULT_CONFIG;
62
+ }
63
+ }
64
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,gCAqBC;AA/BD,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,cAAc,GAAW;IAC7B,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,iBAAiB,EAAE,IAAI;CACxB,CAAC;AAEF,SAAgB,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAEtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE/B,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACzD,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YACtD,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,IAAI;SACpD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC3E,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Config, Violation } from "./types";
2
+ export declare function detectViolations(filePath: string, config: Config): Violation[];
3
+ //# sourceMappingURL=detectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAiF5C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAS9E"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.detectViolations = detectViolations;
37
+ const path = __importStar(require("path"));
38
+ const scanner_1 = require("./scanner");
39
+ const HEX_COLOR = /#([0-9a-fA-F]{3}){1,2}\b/g;
40
+ const FONT_FAMILY = /font-family\s*:\s*['"]?([^'";,}]+)/gi;
41
+ const INLINE_STYLE = /style\s*=\s*\{\s*\{/g;
42
+ function detectColors(lines, file, config) {
43
+ const violations = [];
44
+ const allowedColors = config.colors.map((c) => c.toLowerCase());
45
+ lines.forEach((line, index) => {
46
+ const matches = line.matchAll(HEX_COLOR);
47
+ for (const match of matches) {
48
+ const color = match[0].toLowerCase();
49
+ if (!allowedColors.includes(color)) {
50
+ violations.push({
51
+ file,
52
+ line: index + 1,
53
+ type: "color",
54
+ found: match[0],
55
+ suggestion: "var(--brand-color)",
56
+ });
57
+ }
58
+ }
59
+ });
60
+ return violations;
61
+ }
62
+ function detectFonts(lines, file, config) {
63
+ const violations = [];
64
+ const brandFonts = config.fonts.map((f) => f.toLowerCase());
65
+ lines.forEach((line, index) => {
66
+ const matches = line.matchAll(FONT_FAMILY);
67
+ for (const match of matches) {
68
+ const font = match[1].trim();
69
+ const isAllowed = brandFonts.some((bf) => font.toLowerCase().includes(bf) || bf.includes(font.toLowerCase()));
70
+ if (!isAllowed && font) {
71
+ violations.push({
72
+ file,
73
+ line: index + 1,
74
+ type: "font",
75
+ found: font,
76
+ suggestion: config.fonts[0] || "brand font",
77
+ });
78
+ }
79
+ }
80
+ });
81
+ return violations;
82
+ }
83
+ function detectInlineStyles(lines, file, config) {
84
+ if (config.allowInlineStyles)
85
+ return [];
86
+ const violations = [];
87
+ const isTsxFile = file.endsWith(".tsx") || file.endsWith(".jsx");
88
+ if (!isTsxFile)
89
+ return violations;
90
+ lines.forEach((line, index) => {
91
+ if (INLINE_STYLE.test(line)) {
92
+ violations.push({
93
+ file,
94
+ line: index + 1,
95
+ type: "inline-style",
96
+ found: "inline style object",
97
+ suggestion: "Tailwind class or CSS module",
98
+ });
99
+ }
100
+ INLINE_STYLE.lastIndex = 0;
101
+ });
102
+ return violations;
103
+ }
104
+ function detectViolations(filePath, config) {
105
+ const lines = (0, scanner_1.readFileLines)(filePath);
106
+ const relativePath = path.relative(process.cwd(), filePath);
107
+ return [
108
+ ...detectColors(lines, relativePath, config),
109
+ ...detectFonts(lines, relativePath, config),
110
+ ...detectInlineStyles(lines, relativePath, config),
111
+ ];
112
+ }
113
+ //# sourceMappingURL=detectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectors.js","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const config_1 = require("./config");
5
+ const scanner_1 = require("./scanner");
6
+ const detectors_1 = require("./detectors");
7
+ const output_1 = require("./output");
8
+ function parseArgs(args) {
9
+ return {
10
+ staged: args.includes("--staged") || args.includes("-s"),
11
+ help: args.includes("--help") || args.includes("-h"),
12
+ };
13
+ }
14
+ function printHelp() {
15
+ console.log(`
16
+ blotdev - Scan for brand consistency issues
17
+
18
+ Usage:
19
+ blotdev Scan codebase, output brand-issues.md
20
+ blotdev --staged Scan staged files only (pre-commit)
21
+
22
+ Options:
23
+ -s, --staged Only scan git staged files
24
+ -h, --help Show this help
25
+
26
+ Config:
27
+ Create blot.config.json in project root:
28
+
29
+ {
30
+ "colors": ["#1a1a1a", "#ffffff"],
31
+ "fonts": ["Inter", "Space Grotesk"],
32
+ "allowInlineStyles": false
33
+ }
34
+
35
+ https://blot.dev
36
+ `);
37
+ }
38
+ async function main() {
39
+ const options = parseArgs(process.argv.slice(2));
40
+ if (options.help) {
41
+ printHelp();
42
+ process.exit(0);
43
+ }
44
+ const cwd = process.cwd();
45
+ const config = (0, config_1.loadConfig)(cwd);
46
+ const files = options.staged ? (0, scanner_1.getStagedFiles)(cwd) : await (0, scanner_1.getAllFiles)(cwd);
47
+ if (files.length === 0) {
48
+ console.log("No files to scan.");
49
+ process.exit(0);
50
+ }
51
+ const violations = [];
52
+ for (const file of files) {
53
+ violations.push(...(0, detectors_1.detectViolations)(file, config));
54
+ }
55
+ (0, output_1.printToConsole)(violations, files.length);
56
+ if (!options.staged) {
57
+ (0, output_1.writeMarkdownReport)(violations);
58
+ }
59
+ process.exit(violations.length > 0 ? 1 : 0);
60
+ }
61
+ main().catch((err) => {
62
+ console.error("Error:", err.message || err);
63
+ process.exit(1);
64
+ });
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,qCAAsC;AACtC,uCAAwD;AACxD,2CAA+C;AAC/C,qCAA+D;AAG/D,SAAS,SAAS,CAAC,IAAc;IAC/B,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACxD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;KACrD,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;CAqBb,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,wBAAc,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAA,qBAAW,EAAC,GAAG,CAAC,CAAC;IAE5E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,UAAU,CAAC,IAAI,CAAC,GAAG,IAAA,4BAAgB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,IAAA,uBAAc,EAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,IAAA,4BAAmB,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Violation } from "./types";
2
+ export declare function generateMarkdown(violations: Violation[]): string;
3
+ export declare function writeMarkdownReport(violations: Violation[]): void;
4
+ export declare function printToConsole(violations: Violation[], fileCount: number): void;
5
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAkBpC,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CA2BhE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAIjE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAgC/E"}
package/dist/output.js ADDED
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateMarkdown = generateMarkdown;
37
+ exports.writeMarkdownReport = writeMarkdownReport;
38
+ exports.printToConsole = printToConsole;
39
+ const fs = __importStar(require("fs"));
40
+ function groupByType(violations) {
41
+ return violations.reduce((acc, v) => {
42
+ if (!acc[v.type])
43
+ acc[v.type] = [];
44
+ acc[v.type].push(v);
45
+ return acc;
46
+ }, {});
47
+ }
48
+ function formatViolation(v) {
49
+ const suggestion = v.suggestion ? ` -> \`${v.suggestion}\`` : "";
50
+ return `- [ ] \`${v.file}:${v.line}\` - \`${v.found}\`${suggestion}`;
51
+ }
52
+ function generateMarkdown(violations) {
53
+ if (violations.length === 0) {
54
+ return "# Brand Issues\n\nNo issues found.";
55
+ }
56
+ const grouped = groupByType(violations);
57
+ const sections = ["# Brand Issues\n"];
58
+ if (grouped["color"]?.length) {
59
+ sections.push("## Hardcoded Colors\n");
60
+ sections.push(grouped["color"].map(formatViolation).join("\n"));
61
+ sections.push("");
62
+ }
63
+ if (grouped["font"]?.length) {
64
+ sections.push("## Font Issues\n");
65
+ sections.push(grouped["font"].map(formatViolation).join("\n"));
66
+ sections.push("");
67
+ }
68
+ if (grouped["inline-style"]?.length) {
69
+ sections.push("## Inline Styles\n");
70
+ sections.push(grouped["inline-style"].map(formatViolation).join("\n"));
71
+ sections.push("");
72
+ }
73
+ return sections.join("\n");
74
+ }
75
+ function writeMarkdownReport(violations) {
76
+ const content = generateMarkdown(violations);
77
+ fs.writeFileSync("brand-issues.md", content);
78
+ console.log("\nWrote brand-issues.md");
79
+ }
80
+ function printToConsole(violations, fileCount) {
81
+ console.log(`Scanned ${fileCount} files\n`);
82
+ if (violations.length === 0) {
83
+ console.log("No issues found.");
84
+ return;
85
+ }
86
+ const grouped = groupByType(violations);
87
+ if (grouped["color"]?.length) {
88
+ console.log(`Colors (${grouped["color"].length}):`);
89
+ grouped["color"].forEach((v) => {
90
+ console.log(` ${v.file}:${v.line} ${v.found}`);
91
+ });
92
+ }
93
+ if (grouped["font"]?.length) {
94
+ console.log(`Fonts (${grouped["font"].length}):`);
95
+ grouped["font"].forEach((v) => {
96
+ console.log(` ${v.file}:${v.line} ${v.found}`);
97
+ });
98
+ }
99
+ if (grouped["inline-style"]?.length) {
100
+ console.log(`Inline styles (${grouped["inline-style"].length}):`);
101
+ grouped["inline-style"].forEach((v) => {
102
+ console.log(` ${v.file}:${v.line}`);
103
+ });
104
+ }
105
+ console.log(`\n${violations.length} issues found.`);
106
+ }
107
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function getAllFiles(cwd: string): Promise<string[]>;
2
+ export declare function getStagedFiles(cwd: string): string[];
3
+ export declare function readFileLines(filePath: string): string[];
4
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAepD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAMxD"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getAllFiles = getAllFiles;
37
+ exports.getStagedFiles = getStagedFiles;
38
+ exports.readFileLines = readFileLines;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const child_process_1 = require("child_process");
42
+ const glob_1 = require("glob");
43
+ const EXTENSIONS = ["ts", "tsx", "css", "scss"];
44
+ async function getAllFiles(cwd) {
45
+ const pattern = `**/*.{${EXTENSIONS.join(",")}}`;
46
+ return (0, glob_1.glob)(pattern, {
47
+ cwd,
48
+ ignore: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/.next/**"],
49
+ absolute: true,
50
+ });
51
+ }
52
+ function getStagedFiles(cwd) {
53
+ try {
54
+ const output = (0, child_process_1.execSync)("git diff --cached --name-only --diff-filter=ACM", {
55
+ cwd,
56
+ encoding: "utf-8",
57
+ });
58
+ return output
59
+ .split("\n")
60
+ .filter((f) => f.trim())
61
+ .filter((f) => EXTENSIONS.some((ext) => f.endsWith(`.${ext}`)))
62
+ .map((f) => path.join(cwd, f));
63
+ }
64
+ catch {
65
+ return [];
66
+ }
67
+ }
68
+ function readFileLines(filePath) {
69
+ try {
70
+ return fs.readFileSync(filePath, "utf-8").split("\n");
71
+ }
72
+ catch {
73
+ return [];
74
+ }
75
+ }
76
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,kCAOC;AAED,wCAeC;AAED,sCAMC;AAvCD,uCAAyB;AACzB,2CAA6B;AAC7B,iDAAyC;AACzC,+BAA4B;AAE5B,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAEzC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,OAAO,GAAG,SAAS,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACjD,OAAO,IAAA,WAAI,EAAC,OAAO,EAAE;QACnB,GAAG;QACH,MAAM,EAAE,CAAC,oBAAoB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,CAAC;QAC1E,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,iDAAiD,EAAE;YACzE,GAAG;YACH,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QAEH,OAAO,MAAM;aACV,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;aAC9D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB;IAC5C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface Config {
2
+ colors: string[];
3
+ fonts: string[];
4
+ allowInlineStyles: boolean;
5
+ }
6
+ export interface Violation {
7
+ file: string;
8
+ line: number;
9
+ type: "color" | "font" | "inline-style";
10
+ found: string;
11
+ suggestion?: string;
12
+ }
13
+ export interface Options {
14
+ staged: boolean;
15
+ help: boolean;
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "blotdev",
3
+ "version": "1.0.0",
4
+ "description": "CLI tool to scan codebases for brand consistency issues - catches hardcoded colors, fonts, and styles that should use design tokens.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "blotdev": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "lint",
18
+ "linter",
19
+ "brand",
20
+ "design-system",
21
+ "design-tokens",
22
+ "css",
23
+ "colors",
24
+ "fonts",
25
+ "cli"
26
+ ],
27
+ "author": "Blot Studios, LLC",
28
+ "license": "MIT",
29
+ "homepage": "https://blot.dev",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/blot-studios/blotdev.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/blot-studios/blotdev/issues"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^20.10.0",
39
+ "typescript": "^5.3.0"
40
+ },
41
+ "dependencies": {
42
+ "glob": "^10.3.0"
43
+ },
44
+ "engines": {
45
+ "node": ">=16.0.0"
46
+ },
47
+ "files": [
48
+ "dist",
49
+ "README.md",
50
+ "LICENSE",
51
+ "blot.config.example.json"
52
+ ]
53
+ }