@deneb-ui/cli 2.0.84 → 2.0.86

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
@@ -112,19 +112,47 @@ function isForbiddenFile(filename) {
112
112
  );
113
113
  }
114
114
 
115
- function stripAnsi(str) {
116
- return str.replace(/\x1b\[[0-9;]*m/g, '');
115
+ function getVisualWidth(str) {
116
+ if (!str) return 0;
117
+ const stripped = String(str).replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
118
+ let width = 0;
119
+ for (const char of stripped) {
120
+ const code = char.codePointAt(0);
121
+ if (
122
+ (code >= 0x1100 && code <= 0x115F) ||
123
+ (code >= 0x2E80 && code <= 0xA4CF) ||
124
+ (code >= 0xAC00 && code <= 0xD7A3) ||
125
+ (code >= 0xF900 && code <= 0xFAFF) ||
126
+ (code >= 0xFE10 && code <= 0xFE19) ||
127
+ (code >= 0xFE30 && code <= 0xFE6F) ||
128
+ (code >= 0xFF00 && code <= 0xFF60) ||
129
+ (code >= 0xFFE0 && code <= 0xFFE6) ||
130
+ (code >= 0x1F000 && code <= 0x1FAFF) ||
131
+ (code >= 0x2600 && code <= 0x27BF)
132
+ ) {
133
+ width += 2;
134
+ } else if (code > 0xFFFF) {
135
+ width += 2;
136
+ } else {
137
+ width += 1;
138
+ }
139
+ }
140
+ return width;
117
141
  }
118
142
 
119
- function createBox(lines, width = 55) {
143
+ function createBox(lines, preferredWidth = 58) {
120
144
  const cyan = '\x1b[36m';
121
145
  const reset = '\x1b[0m';
122
- const top = ` ${cyan}╔${'═'.repeat(width)}╗${reset}`;
123
- const bottom = ` ${cyan}╚${'═'.repeat(width)}╝${reset}`;
146
+ const visualLengths = lines.map((l) => getVisualWidth(l));
147
+ const maxLineVisual = Math.max(...visualLengths, 0);
148
+ const boxWidth = Math.max(preferredWidth, maxLineVisual + 4);
124
149
 
125
- const rows = lines.map((line) => {
126
- const rawLen = stripAnsi(line).length;
127
- const padTotal = Math.max(0, width - rawLen);
150
+ const top = ` ${cyan}╔${'═'.repeat(boxWidth)}╗${reset}`;
151
+ const bottom = ` ${cyan}╚${'═'.repeat(boxWidth)}╝${reset}`;
152
+
153
+ const rows = lines.map((line, idx) => {
154
+ const rawLen = visualLengths[idx];
155
+ const padTotal = Math.max(0, boxWidth - rawLen);
128
156
  const padLeft = Math.floor(padTotal / 2);
129
157
  const padRight = padTotal - padLeft;
130
158
  return ` ${cyan}║${reset}${' '.repeat(padLeft)}${line}${' '.repeat(padRight)}${cyan}║${reset}`;
@@ -1210,11 +1238,16 @@ async function initProject(targetInput, options = {}) {
1210
1238
  }
1211
1239
  }
1212
1240
 
1213
- if (!skipInstall) {
1241
+ if (!skipInstall && !process.env.DENEB_SKIP_FONTS) {
1214
1242
  try {
1215
1243
  const { runFontsInstall } = require('../src/tools/deneb-fonts.cjs');
1244
+ const plannedFontArgs = [];
1245
+ const fontList = conversionRes && Array.isArray(conversionRes.fontIds) ? conversionRes.fontIds : [];
1246
+ for (const id of fontList) {
1247
+ plannedFontArgs.push('--font', id);
1248
+ }
1216
1249
  console.log(`\n\x1b[36mAa Downloading and configuring DENEB Google Fonts...\x1b[0m`);
1217
- runFontsInstall(targetDir, []);
1250
+ runFontsInstall(targetDir, plannedFontArgs);
1218
1251
  } catch (err) {
1219
1252
  console.log(`\n\x1b[33m! Fonts were not installed automatically: ${err.message}. Run \x1b[1mdeneb fonts install .\x1b[0m\x1b[0m`);
1220
1253
  }
@@ -1469,12 +1502,13 @@ if (command === 'validate' && (commandArgs[0] === 'and' || commandArgs[0] === '&
1469
1502
  commandArgs = commandArgs.slice(2);
1470
1503
  }
1471
1504
 
1472
- if (command === 'init') {
1505
+ if (command === 'init' || command === 'arc') {
1473
1506
  let targetInput = '.';
1474
1507
  let recipeName = null;
1475
1508
  let dryRun = false;
1476
1509
  let explain = false;
1477
1510
  let legacy = false;
1511
+ let strict = false;
1478
1512
  let telemetry = 'off';
1479
1513
  let aiEnabled = false;
1480
1514
  let aiDryRun = false;
@@ -1490,6 +1524,8 @@ if (command === 'init') {
1490
1524
  explain = true;
1491
1525
  } else if (arg === '--legacy') {
1492
1526
  legacy = true;
1527
+ } else if (arg === '--strict') {
1528
+ strict = true;
1493
1529
  } else if (arg === '--ai') {
1494
1530
  aiEnabled = true;
1495
1531
  } else if (arg === '--ai-dry-run') {
@@ -1503,10 +1539,44 @@ if (command === 'init') {
1503
1539
  targetInput = arg;
1504
1540
  }
1505
1541
  }
1506
- initProject(targetInput, { recipeName, dryRun, explain, legacy, telemetry, aiEnabled, aiDryRun }).catch((err) => {
1542
+ initProject(targetInput, { recipeName, dryRun, explain, legacy, strict, telemetry, aiEnabled, aiDryRun }).catch((err) => {
1507
1543
  console.error(`\x1b[31mError:\x1b[0m ${err.message}`);
1508
1544
  process.exit(1);
1509
1545
  });
1546
+ } else if (command === 'explain') {
1547
+ const fileInput = commandArgs.find((a) => !a.startsWith('-'));
1548
+ if (!fileInput) {
1549
+ console.error('\x1b[31mError:\x1b[0m Please specify a component file to explain (e.g. deneb explain src/components/Hero.tsx)');
1550
+ process.exit(1);
1551
+ }
1552
+ const isJson = commandArgs.includes('--json');
1553
+ try {
1554
+ const { explainFile, printExplanation } = require('../src/arc/explain.cjs');
1555
+ const explanation = explainFile(fileInput, { root: '.' });
1556
+ if (isJson) {
1557
+ console.log(JSON.stringify(explanation, null, 2));
1558
+ } else {
1559
+ printExplanation(explanation);
1560
+ }
1561
+ } catch (err) {
1562
+ console.error(`\x1b[31mError:\x1b[0m ${err.message}`);
1563
+ process.exit(1);
1564
+ }
1565
+ } else if (command === 'diff') {
1566
+ let targetInput = commandArgs.find((a) => !a.startsWith('-')) || '.';
1567
+ const isJson = commandArgs.includes('--json');
1568
+ try {
1569
+ const { generateArcDiff, printDiff } = require('../src/arc/diff.cjs');
1570
+ const diffs = generateArcDiff(targetInput);
1571
+ if (isJson) {
1572
+ console.log(JSON.stringify(diffs, null, 2));
1573
+ } else {
1574
+ printDiff(diffs);
1575
+ }
1576
+ } catch (err) {
1577
+ console.error(`\x1b[31mError:\x1b[0m ${err.message}`);
1578
+ process.exit(1);
1579
+ }
1510
1580
  } else if (command === 'create') {
1511
1581
  createTemplate(commandArgs[0]);
1512
1582
  } else if (command === 'add') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deneb-ui/cli",
3
- "version": "2.0.84",
3
+ "version": "2.0.86",
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.84",
52
+ "@deneb-ui/core": "^2.0.86",
53
53
  "@octokit/rest": "^22.0.1",
54
54
  "adm-zip": "^0.6.0",
55
55
  "dotenv": "^17.4.2",