blotdev 1.1.0 → 1.4.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/README.md CHANGED
@@ -1,29 +1,33 @@
1
1
  # blotdev
2
2
 
3
- Scan codebases for brand consistency issues. Catches hardcoded colors, fonts, and styles that should use design tokens.
3
+ Scan codebases for brand consistency issues. Catches hardcoded colors, undefined CSS tokens, and non-brand fonts.
4
4
 
5
- ## Install
5
+ ## Quick Start
6
6
 
7
7
  ```bash
8
- npm install blotdev
8
+ npx blotdev --init
9
+ npx blotdev
9
10
  ```
10
11
 
11
- ## Quick Start
12
+ That's it. The first command scans your codebase and creates `blot.config.json` with all detected colors, fonts, and CSS tokens. The second command scans for violations.
12
13
 
13
- ```bash
14
- npx blotdev --init # create blot.config.json
15
- npx blotdev # scan and output brand-issues.md
16
- ```
14
+ ## What it Checks
15
+
16
+ - **Hardcoded colors** - hex values not in your config
17
+ - **Undefined tokens** - `var(--color-foo)` where `--color-foo` isn't defined
18
+ - **Non-brand fonts** - font-family declarations not in your config
19
+ - **Inline styles** - `style={{}}` in JSX (optional)
17
20
 
18
21
  ## Config
19
22
 
20
- Edit `blot.config.json` with your brand values:
23
+ `blot.config.json` is auto-generated but you can edit it:
21
24
 
22
25
  ```json
23
26
  {
24
- "colors": ["#1a1a1a", "#ffffff", "#FF6B35"],
25
- "fonts": ["Inter", "Space Grotesk"],
26
- "allowInlineStyles": false
27
+ "colors": ["#1a1a1a", "#ffffff"],
28
+ "fonts": ["Inter"],
29
+ "tokens": ["--color-ink", "--color-paper"],
30
+ "allowInlineStyles": true
27
31
  }
28
32
  ```
29
33
 
@@ -31,32 +35,16 @@ Edit `blot.config.json` with your brand values:
31
35
  |--------|-------------|
32
36
  | `colors` | Allowed hex colors |
33
37
  | `fonts` | Allowed font families |
38
+ | `tokens` | Defined CSS custom properties |
34
39
  | `allowInlineStyles` | Allow `style={{}}` in JSX |
35
40
 
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
41
  ## Pre-commit
54
42
 
55
43
  ```bash
56
44
  npx blotdev --staged
57
45
  ```
58
46
 
59
- With lint-staged:
47
+ Exits with code 1 if issues found. Use with husky/lint-staged:
60
48
 
61
49
  ```json
62
50
  {
@@ -68,11 +56,11 @@ With lint-staged:
68
56
 
69
57
  ## Options
70
58
 
71
- | Flag | Description |
72
- |------|-------------|
73
- | `-i, --init` | Create config file |
74
- | `-s, --staged` | Scan staged files only |
75
- | `-h, --help` | Show help |
59
+ ```
60
+ -i, --init Create config (auto-detects values)
61
+ -s, --staged Scan staged files only
62
+ -h, --help Show help
63
+ ```
76
64
 
77
65
  ## License
78
66
 
@@ -1,5 +1,6 @@
1
1
  {
2
- "colors": ["#1a1a1a", "#ffffff", "#FF6B35"],
3
- "fonts": ["Inter", "Space Grotesk"],
4
- "allowInlineStyles": false
2
+ "colors": ["#1a1a1a", "#ffffff"],
3
+ "fonts": ["Inter"],
4
+ "tokens": ["--color-ink", "--color-paper"],
5
+ "allowInlineStyles": true
5
6
  }
@@ -1 +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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AASjC,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAsB9D"}
package/dist/config.js CHANGED
@@ -39,12 +39,13 @@ const path = __importStar(require("path"));
39
39
  const DEFAULT_CONFIG = {
40
40
  colors: [],
41
41
  fonts: [],
42
+ tokens: [],
42
43
  allowInlineStyles: true,
43
44
  };
44
45
  function loadConfig(cwd = process.cwd()) {
45
46
  const configPath = path.join(cwd, "blot.config.json");
46
47
  if (!fs.existsSync(configPath)) {
47
- console.error("Warning: No blot.config.json found, using defaults");
48
+ console.error("No blot.config.json found. Run: npx blotdev --init");
48
49
  return DEFAULT_CONFIG;
49
50
  }
50
51
  try {
@@ -53,11 +54,12 @@ function loadConfig(cwd = process.cwd()) {
53
54
  return {
54
55
  colors: Array.isArray(parsed.colors) ? parsed.colors : [],
55
56
  fonts: Array.isArray(parsed.fonts) ? parsed.fonts : [],
57
+ tokens: Array.isArray(parsed.tokens) ? parsed.tokens : [],
56
58
  allowInlineStyles: parsed.allowInlineStyles ?? true,
57
59
  };
58
60
  }
59
61
  catch {
60
- console.error("Warning: Failed to parse blot.config.json, using defaults");
62
+ console.error("Failed to parse blot.config.json");
61
63
  return DEFAULT_CONFIG;
62
64
  }
63
65
  }
@@ -1 +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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,gCAsBC;AAjCD,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,cAAc,GAAW;IAC7B,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,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,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACzD,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,IAAI;SACpD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -1 +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"}
1
+ {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA0G5C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAU9E"}
package/dist/detectors.js CHANGED
@@ -39,6 +39,7 @@ const scanner_1 = require("./scanner");
39
39
  const HEX_COLOR = /#([0-9a-fA-F]{3}){1,2}\b/g;
40
40
  const FONT_FAMILY = /font-family\s*:\s*['"]?([^'";,}]+)/gi;
41
41
  const INLINE_STYLE = /style\s*=\s*\{\s*\{/g;
42
+ const CSS_VAR_USE = /var\(--([a-zA-Z0-9-]+)\)/g;
42
43
  function detectColors(lines, file, config) {
43
44
  const violations = [];
44
45
  const allowedColors = config.colors.map((c) => c.toLowerCase());
@@ -101,6 +102,27 @@ function detectInlineStyles(lines, file, config) {
101
102
  });
102
103
  return violations;
103
104
  }
105
+ function detectUndefinedTokens(lines, file, config) {
106
+ if (config.tokens.length === 0)
107
+ return [];
108
+ const violations = [];
109
+ const definedTokens = config.tokens.map((t) => t.toLowerCase());
110
+ lines.forEach((line, index) => {
111
+ const matches = line.matchAll(CSS_VAR_USE);
112
+ for (const match of matches) {
113
+ const token = `--${match[1]}`.toLowerCase();
114
+ if (!definedTokens.includes(token)) {
115
+ violations.push({
116
+ file,
117
+ line: index + 1,
118
+ type: "undefined-token",
119
+ found: `var(--${match[1]})`,
120
+ });
121
+ }
122
+ }
123
+ });
124
+ return violations;
125
+ }
104
126
  function detectViolations(filePath, config) {
105
127
  const lines = (0, scanner_1.readFileLines)(filePath);
106
128
  const relativePath = path.relative(process.cwd(), filePath);
@@ -108,6 +130,7 @@ function detectViolations(filePath, config) {
108
130
  ...detectColors(lines, relativePath, config),
109
131
  ...detectFonts(lines, relativePath, config),
110
132
  ...detectInlineStyles(lines, relativePath, config),
133
+ ...detectUndefinedTokens(lines, relativePath, config),
111
134
  ];
112
135
  }
113
136
  //# sourceMappingURL=detectors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectors.js","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"detectors.js","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -40,6 +40,9 @@ const config_1 = require("./config");
40
40
  const scanner_1 = require("./scanner");
41
41
  const detectors_1 = require("./detectors");
42
42
  const output_1 = require("./output");
43
+ const HEX_COLOR = /#([0-9a-fA-F]{3}){1,2}\b/g;
44
+ const FONT_FAMILY = /font-family\s*:\s*['"]?([^'";,}]+)/gi;
45
+ const CSS_VAR_DEF = /--([a-zA-Z0-9-]+)\s*:/g;
43
46
  function parseArgs(args) {
44
47
  return {
45
48
  staged: args.includes("--staged") || args.includes("-s"),
@@ -48,35 +51,59 @@ function parseArgs(args) {
48
51
  };
49
52
  }
50
53
  function printHelp() {
51
- console.log(`
52
- blotdev - Scan for brand consistency issues
54
+ console.log(`blotdev - Scan for brand consistency issues
53
55
 
54
56
  Usage:
55
57
  blotdev Scan codebase, output brand-issues.md
56
- blotdev --init Create blot.config.json
58
+ blotdev --init Create config with auto-detected values
57
59
  blotdev --staged Scan staged files only (pre-commit)
58
60
 
59
61
  Options:
60
- -i, --init Create config file
61
- -s, --staged Only scan git staged files
62
- -h, --help Show this help
62
+ -i, --init Create blot.config.json
63
+ -s, --staged Scan staged files only
64
+ -h, --help Show help
63
65
 
64
- https://blot.dev
65
- `);
66
+ https://blot.dev`);
66
67
  }
67
- function createConfig() {
68
- const configPath = path.join(process.cwd(), "blot.config.json");
68
+ async function createConfig() {
69
+ const cwd = process.cwd();
70
+ const configPath = path.join(cwd, "blot.config.json");
69
71
  if (fs.existsSync(configPath)) {
70
72
  console.error("blot.config.json already exists");
71
73
  process.exit(1);
72
74
  }
75
+ const files = await (0, scanner_1.getAllFiles)(cwd);
76
+ const colors = new Set();
77
+ const fonts = new Set();
78
+ const tokens = new Set();
79
+ for (const file of files) {
80
+ const lines = (0, scanner_1.readFileLines)(file);
81
+ for (const line of lines) {
82
+ const colorMatches = line.matchAll(HEX_COLOR);
83
+ for (const match of colorMatches) {
84
+ colors.add(match[0].toLowerCase());
85
+ }
86
+ const fontMatches = line.matchAll(FONT_FAMILY);
87
+ for (const match of fontMatches) {
88
+ const font = match[1].trim();
89
+ if (font && !font.startsWith("var(")) {
90
+ fonts.add(font);
91
+ }
92
+ }
93
+ const tokenMatches = line.matchAll(CSS_VAR_DEF);
94
+ for (const match of tokenMatches) {
95
+ tokens.add(`--${match[1]}`);
96
+ }
97
+ }
98
+ }
73
99
  const config = {
74
- colors: [],
75
- fonts: [],
100
+ colors: Array.from(colors).sort(),
101
+ fonts: Array.from(fonts).sort(),
102
+ tokens: Array.from(tokens).sort(),
76
103
  allowInlineStyles: true,
77
104
  };
78
105
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
79
- console.log("Created blot.config.json");
106
+ console.log(`blot.config.json (${colors.size} colors, ${fonts.size} fonts, ${tokens.size} tokens)`);
80
107
  }
81
108
  async function main() {
82
109
  const options = parseArgs(process.argv.slice(2));
@@ -85,14 +112,14 @@ async function main() {
85
112
  process.exit(0);
86
113
  }
87
114
  if (options.init) {
88
- createConfig();
115
+ await createConfig();
89
116
  process.exit(0);
90
117
  }
91
118
  const cwd = process.cwd();
92
119
  const config = (0, config_1.loadConfig)(cwd);
93
120
  const files = options.staged ? (0, scanner_1.getStagedFiles)(cwd) : await (0, scanner_1.getAllFiles)(cwd);
94
121
  if (files.length === 0) {
95
- console.log("No files to scan.");
122
+ console.log("No files found.");
96
123
  process.exit(0);
97
124
  }
98
125
  const violations = [];
@@ -106,7 +133,7 @@ async function main() {
106
133
  process.exit(violations.length > 0 ? 1 : 0);
107
134
  }
108
135
  main().catch((err) => {
109
- console.error("Error:", err.message || err);
136
+ console.error("error:", err.message || err);
110
137
  process.exit(1);
111
138
  });
112
139
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +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"}
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,CAiChE;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,CAsC/E"}
package/dist/output.js CHANGED
@@ -70,38 +70,49 @@ function generateMarkdown(violations) {
70
70
  sections.push(grouped["inline-style"].map(formatViolation).join("\n"));
71
71
  sections.push("");
72
72
  }
73
+ if (grouped["undefined-token"]?.length) {
74
+ sections.push("## Undefined Tokens\n");
75
+ sections.push(grouped["undefined-token"].map(formatViolation).join("\n"));
76
+ sections.push("");
77
+ }
73
78
  return sections.join("\n");
74
79
  }
75
80
  function writeMarkdownReport(violations) {
76
81
  const content = generateMarkdown(violations);
77
82
  fs.writeFileSync("brand-issues.md", content);
78
- console.log("\nWrote brand-issues.md");
83
+ console.log("wrote brand-issues.md");
79
84
  }
80
85
  function printToConsole(violations, fileCount) {
81
- console.log(`Scanned ${fileCount} files\n`);
82
86
  if (violations.length === 0) {
83
- console.log("No issues found.");
87
+ console.log(`${fileCount} files, no issues`);
84
88
  return;
85
89
  }
86
90
  const grouped = groupByType(violations);
91
+ const parts = [];
87
92
  if (grouped["color"]?.length) {
88
- console.log(`Colors (${grouped["color"].length}):`);
93
+ parts.push(`${grouped["color"].length} colors`);
89
94
  grouped["color"].forEach((v) => {
90
95
  console.log(` ${v.file}:${v.line} ${v.found}`);
91
96
  });
92
97
  }
93
98
  if (grouped["font"]?.length) {
94
- console.log(`Fonts (${grouped["font"].length}):`);
99
+ parts.push(`${grouped["font"].length} fonts`);
95
100
  grouped["font"].forEach((v) => {
96
101
  console.log(` ${v.file}:${v.line} ${v.found}`);
97
102
  });
98
103
  }
99
104
  if (grouped["inline-style"]?.length) {
100
- console.log(`Inline styles (${grouped["inline-style"].length}):`);
105
+ parts.push(`${grouped["inline-style"].length} inline styles`);
101
106
  grouped["inline-style"].forEach((v) => {
102
107
  console.log(` ${v.file}:${v.line}`);
103
108
  });
104
109
  }
105
- console.log(`\n${violations.length} issues found.`);
110
+ if (grouped["undefined-token"]?.length) {
111
+ parts.push(`${grouped["undefined-token"].length} undefined tokens`);
112
+ grouped["undefined-token"].forEach((v) => {
113
+ console.log(` ${v.file}:${v.line} ${v.found}`);
114
+ });
115
+ }
116
+ console.log(`\n${fileCount} files, ${parts.join(", ")}`);
106
117
  }
107
118
  //# sourceMappingURL=output.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  export interface Config {
2
2
  colors: string[];
3
3
  fonts: string[];
4
+ tokens: string[];
4
5
  allowInlineStyles: boolean;
5
6
  }
6
7
  export interface Violation {
7
8
  file: string;
8
9
  line: number;
9
- type: "color" | "font" | "inline-style";
10
+ type: "color" | "font" | "inline-style" | "undefined-token";
10
11
  found: string;
11
12
  suggestion?: string;
12
13
  }
@@ -1 +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;IACd,IAAI,EAAE,OAAO,CAAC;CACf"}
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,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,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,GAAG,iBAAiB,CAAC;IAC5D,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;IACd,IAAI,EAAE,OAAO,CAAC;CACf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blotdev",
3
- "version": "1.1.0",
3
+ "version": "1.4.0",
4
4
  "description": "CLI tool to scan codebases for brand consistency issues - catches hardcoded colors, fonts, and styles that should use design tokens.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",