@deneb-ui/cli 2.0.117 → 2.0.119

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/bin/index.js CHANGED
@@ -86,6 +86,7 @@ const args = process.argv.slice(2);
86
86
  const toolsDir = path.join(__dirname, '..', 'src', 'tools');
87
87
 
88
88
  const FORBIDDEN_DIRS = new Set([
89
+ '.deneb',
89
90
  '.git',
90
91
  '.next',
91
92
  '.turbo',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deneb-ui/cli",
3
- "version": "2.0.117",
3
+ "version": "2.0.119",
4
4
  "description": "Official DENEB CLI — scaffold, convert, validate, and package Fivora-ready storefront templates.",
5
5
  "bin": {
6
6
  "deneb": "bin/index.js",
@@ -49,7 +49,7 @@
49
49
  "license": "MIT",
50
50
  "dependencies": {
51
51
  "@babel/parser": "^7.28.0",
52
- "@deneb-ui/core": "^2.0.117",
52
+ "@deneb-ui/core": "^2.0.119",
53
53
  "@octokit/rest": "^22.0.1",
54
54
  "adm-zip": "^0.6.0",
55
55
  "dotenv": "^17.4.2",
@@ -4066,3 +4066,20 @@ test('ARC auto-editability fixer handles multi-industry card collections (books,
4066
4066
  assert.ok(keys.includes('price'));
4067
4067
  });
4068
4068
 
4069
+ test('ARC recognizes theme toggles, stars, quotes, and reset icons as utility/decorative icons', () => {
4070
+ const { isUtilityIcon, isFeatureIcon } = require('../adapters.cjs');
4071
+ const { isStaticSkipText } = require('../semantic.cjs');
4072
+
4073
+ const decorativeIcons = ['Sun', 'Moon', 'Sparkles', 'Quote', 'Star', 'RotateCcw', 'RefreshCw'];
4074
+ for (const name of decorativeIcons) {
4075
+ assert.equal(isUtilityIcon(name), true, `${name} should be recognized as utility/decorative icon`);
4076
+ assert.equal(isFeatureIcon(name, 'lucide-react'), false, `${name} should not be classified as feature icon`);
4077
+ }
4078
+
4079
+ assert.equal(isStaticSkipText('Theme Mode'), true);
4080
+ assert.equal(isStaticSkipText('Toggle theme'), true);
4081
+ assert.equal(isStaticSkipText('Dark'), true);
4082
+ assert.equal(isStaticSkipText('Light'), true);
4083
+ });
4084
+
4085
+
@@ -20,7 +20,7 @@ const DECORATIVE_TAGS = new Set([
20
20
  ]);
21
21
  const SKIP_TAGS = new Set([
22
22
  'script', 'style', 'link', 'meta', 'head', 'html', 'Fragment', 'Suspense',
23
- 'StrictMode', 'ErrorBoundary',
23
+ 'StrictMode', 'ErrorBoundary', 'ThemeToggle', 'ThemeStyles',
24
24
  ]);
25
25
  const HEADING_TAGS = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'Heading', 'Title', 'CardTitle', 'ModalHeader', 'DialogTitle']);
26
26
  const TEXT_TAGS = new Set(['p', 'span', 'li', 'blockquote', 'figcaption', 'label', 'CardDescription', 'Description', 'Subtitle', 'Typography', 'Text', 'Badge', 'badge']);
@@ -35,14 +35,23 @@ const UTILITY_ICON_PATTERNS = [
35
35
  /^(Chevron|Arrow|Move|Caret|Angle|Sort|Chevrons)/i,
36
36
  /^(X|Close|Menu|MenuAlt|Hamburger)/i,
37
37
  /^(Loader|Spinner)/i,
38
+ /^(Sun|Moon|Sparkles?|Theme|SunMoon|HalfMoon)/i,
39
+ /^(Quote|Star)/i,
40
+ /^(RotateCcw|RotateCw|Refresh|Undo|Redo|Reset)/i,
38
41
  ];
39
42
 
40
43
  function isUtilityIcon(name) {
41
44
  if (!name) return false;
42
- const clean = String(name).replace(/Icon$/i, '');
45
+ const clean = String(name)
46
+ .replace(/^(Lucide|Fa|Hi|Io|Md)/, '')
47
+ .replace(/Icon$/i, '');
43
48
  if (UTILITY_ICON_PATTERNS.some((re) => re.test(clean))) return true;
44
49
  const lower = clean.toLowerCase();
45
- return ['x', 'close', 'menu', 'spinner', 'loader'].includes(lower);
50
+ return [
51
+ 'x', 'close', 'menu', 'spinner', 'loader',
52
+ 'sun', 'moon', 'sparkle', 'sparkles', 'theme', 'quote', 'star',
53
+ 'rotate-ccw', 'rotateccw', 'rotate-cw', 'rotatecw', 'refresh', 'reset',
54
+ ].includes(lower);
46
55
  }
47
56
 
48
57
  function isIconComponent(name, importSource) {
@@ -107,12 +107,15 @@ function isMeaningfulVisibleText(text, isLogoOrList = false) {
107
107
  return true;
108
108
  }
109
109
 
110
+ const THEME_UI_TEXT_RE = /^(dark|light|system|theme|theme\s*mode|toggle\s*theme)$/i;
111
+
110
112
  function isDecorativeCopy(text, tag, className) {
111
113
  const value = String(text || '').replace(/\s+/g, ' ').trim();
112
114
  if (!value) return true;
113
115
  if (CHROME_TEXT_RE.test(value)) return true;
116
+ if (THEME_UI_TEXT_RE.test(value)) return true;
114
117
  if (CART_CHROME_RE.test(value) && /cart|drawer|qty|quantity/i.test(className || '')) return true;
115
- if (DECORATIVE_TAGS.has(tag) || tag === 'svg') return true;
118
+ if (DECORATIVE_TAGS.has(tag) || tag === 'svg' || isUtilityIcon(tag)) return true;
116
119
  if (/\bsr-only\b|\bhidden\b/.test(className || '')) return true;
117
120
  return false;
118
121
  }
@@ -85,11 +85,14 @@ function normalizeText(value) {
85
85
  return String(value || '').replace(/\s+/g, ' ').trim();
86
86
  }
87
87
 
88
+ const THEME_UI_TEXT_RE = /^(dark|light|system|theme|theme\s*mode|toggle\s*theme)$/i;
89
+
88
90
  function isStaticSkipText(text, isLogoContext = false) {
89
91
  const value = normalizeText(text);
90
92
  if (!value) return true;
91
93
  if (value.length < 2 && !isLogoContext) return true;
92
94
  if (TECHNICAL_TEXT_RE.test(value)) return true;
95
+ if (THEME_UI_TEXT_RE.test(value)) return true;
93
96
  if (/^[{}`\\]/.test(value)) return true;
94
97
  if (/^https?:\/\/(localhost|127\.0\.0\.1)/i.test(value)) return true;
95
98
  return false;