@birdapi/velinstyle 1.2.0 → 1.2.2
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.de.md +150 -24
- package/README.md +155 -33
- package/cli/__fixtures__/atelier-library/showcases/01-login/app.css +1 -0
- package/cli/__fixtures__/atelier-library/showcases/01-login/app.js +2 -0
- package/cli/__fixtures__/atelier-library/showcases/01-login/index.html +5 -0
- package/cli/__fixtures__/atelier-library/showcases/04-pricing/app.css +1 -0
- package/cli/__fixtures__/atelier-library/showcases/04-pricing/app.js +2 -0
- package/cli/__fixtures__/atelier-library/showcases/04-pricing/index.html +5 -0
- package/cli/__fixtures__/atelier-library/showcases/36-calendar/app.css +1 -0
- package/cli/__fixtures__/atelier-library/showcases/36-calendar/app.js +2 -0
- package/cli/__fixtures__/atelier-library/showcases/36-calendar/index.html +5 -0
- package/cli/atelier-catalog.json +1267 -0
- package/cli/atelier-formats.js +159 -0
- package/cli/atelier.js +382 -0
- package/cli/blueprints/empty-state.html +3 -5
- package/cli/cli-manifest.json +23 -10
- package/cli/docgen/extract-attributes.js +2 -0
- package/cli/docgen/extract-cli.js +1 -1
- package/cli/index.js +181 -6
- package/cli/production/component-graph.json +166 -0
- package/cli/production/explain.js +52 -0
- package/cli/production/extract.js +238 -0
- package/cli/production/graph.js +102 -0
- package/cli/production/report.js +78 -0
- package/cli/production/run.js +312 -0
- package/cli/production/trim-css.js +177 -0
- package/cli/production/trim-fonts.js +23 -0
- package/cli/production/trim-icons.js +38 -0
- package/cli/production/trim-js.js +48 -0
- package/cli/production/trim-motion.js +22 -0
- package/cli/production/trim-themes.js +50 -0
- package/cli/production/watch.js +38 -0
- package/cli/review.js +48 -1
- package/cli/scripts/write-atelier-fixtures.mjs +33 -0
- package/cli/transparency.js +221 -0
- package/components/index.js +3 -0
- package/components/runtime/component-loaders.js +3 -0
- package/components/velin-drawer.js +43 -4
- package/components/velin-empty-state.js +83 -0
- package/components/velin-modal.js +76 -15
- package/components/velin-otp-input.js +220 -0
- package/components/velin-password-strength.js +147 -0
- package/components/velin-sheet.js +49 -4
- package/core/a11y/component-contracts.json +23 -4
- package/core/attributes/registry.js +14 -0
- package/core/meta/knowledge/components.json +75 -3
- package/core/meta/schema.js +10 -0
- package/core/transparency/attach.js +74 -0
- package/core/transparency/claims.js +97 -0
- package/core/transparency/doctor.js +142 -0
- package/core/transparency/engine.js +75 -0
- package/core/transparency/export.js +98 -0
- package/core/transparency/index.js +30 -0
- package/core/transparency/migrate.js +130 -0
- package/core/transparency/normalize.js +125 -0
- package/core/transparency/policy.js +105 -0
- package/core/transparency/providers.js +235 -0
- package/core/transparency/registry.js +104 -0
- package/core/transparency/renderer.js +111 -0
- package/core/transparency/reporter.js +113 -0
- package/core/transparency/validator.js +112 -0
- package/dist/chunks/attach-H2ZSEAE6.js +365 -0
- package/dist/chunks/attributes-2ORR27KA.js +404 -0
- package/dist/chunks/attributes-DZCXX2RZ.js +404 -0
- package/dist/chunks/chunk-CQMTCEI6.js +113 -0
- package/dist/chunks/chunk-Y6HN7HWX.js +116 -0
- package/dist/chunks/runtime-entry.js +1 -1
- package/dist/chunks/velin-drawer-A7Q7EBOS.js +162 -0
- package/dist/chunks/velin-empty-state-3NTUH2RF.js +81 -0
- package/dist/chunks/velin-modal-3MV4FYBK.js +231 -0
- package/dist/chunks/velin-otp-input-PSK42MM6.js +207 -0
- package/dist/chunks/velin-password-strength-TAXMLSED.js +136 -0
- package/dist/chunks/velin-sheet-N2VVYXFP.js +157 -0
- package/dist/llms.txt +5 -4
- package/dist/search-index.json +94 -5
- package/dist/velin-agent.json +290 -23
- package/dist/velinstyle-components.iife.js +3189 -2202
- package/dist/velinstyle-components.js +3187 -2196
- package/dist/velinstyle-components.min.js +261 -119
- package/dist/velinstyle.css +214 -6
- package/dist/velinstyle.d.ts +3 -0
- package/dist/velinstyle.min.css +1 -1
- package/package.json +143 -142
- package/packages/velinstyle-skills/catalog.json +1 -1
- package/src/components/data-table.css +19 -0
- package/src/components/empty-auth.css +33 -0
- package/src/components/table.css +16 -6
- package/src/components/transparency.css +138 -0
- package/src/velinstyle.css +2 -0
package/cli/index.js
CHANGED
|
@@ -45,6 +45,7 @@ const LAYER_FILES = {
|
|
|
45
45
|
'components/timeline.css', 'components/stepper.css', 'components/stat.css',
|
|
46
46
|
'components/drawer.css', 'components/input-group.css', 'components/form-validation.css', 'components/collapse.css',
|
|
47
47
|
'components/calendar-dropzone.css',
|
|
48
|
+
'components/transparency.css',
|
|
48
49
|
],
|
|
49
50
|
utilities: [
|
|
50
51
|
'utilities/color.css', 'utilities/spacing.css', 'utilities/display.css',
|
|
@@ -91,6 +92,8 @@ function help() {
|
|
|
91
92
|
${C.bold('Usage:')}
|
|
92
93
|
velinstyle init Create velinstyle.config.js
|
|
93
94
|
velinstyle build Build custom CSS with selected layers
|
|
95
|
+
velinstyle build --production Content-aware production output (CSS/JS/themes/icons)
|
|
96
|
+
velinstyle production [path] Alias for build --production
|
|
94
97
|
velinstyle themes List available themes
|
|
95
98
|
velinstyle add <name> Add a single component CSS
|
|
96
99
|
velinstyle icons <subcommand> Manage icon providers
|
|
@@ -101,9 +104,14 @@ function help() {
|
|
|
101
104
|
velinstyle create <kind> [dir] Scaffold: landing|dashboard|docs|auth
|
|
102
105
|
velinstyle serve [dir] Static preview server (default port 4173)
|
|
103
106
|
velinstyle doctor Check dist, icons, config, Windows ESM paths
|
|
104
|
-
velinstyle
|
|
107
|
+
velinstyle transparency <sub> Transparency Framework: doctor|validate|report|export|migrate
|
|
108
|
+
velinstyle check [path] doctor + blueprint --strict + scan + review + transparency
|
|
105
109
|
velinstyle scaffold "<prompt>" Plan-first page HTML or recipe fragment
|
|
110
|
+
velinstyle scaffold --atelier 04,07 Compose Atelier Library ids (beta)
|
|
106
111
|
velinstyle plan "<prompt>" Emit page plan JSON (no HTML)
|
|
112
|
+
velinstyle plan --atelier 04,07 Emit plan JSON for Atelier ids (beta)
|
|
113
|
+
velinstyle atelier <num|id> Pull curated Atelier Library showcase
|
|
114
|
+
velinstyle atelier list List curated Library numbers/ids
|
|
107
115
|
velinstyle review [file|html] Design / a11y / SEO / conversion review gate
|
|
108
116
|
velinstyle wc api <tag> Human-readable Web Component API from source
|
|
109
117
|
velinstyle layout <sub> Responsive layout audit and fixes
|
|
@@ -145,11 +153,27 @@ function help() {
|
|
|
145
153
|
velinstyle scaffold "<prompt>" Plan → render → review for pages; recipes for fragments
|
|
146
154
|
velinstyle scaffold list-intents Show recipe intent keywords
|
|
147
155
|
velinstyle scaffold "<prompt>" -o out.html [--json]
|
|
156
|
+
velinstyle scaffold --atelier 04,07 [-o page.html] [--from <library>] Compose Library showcases (beta)
|
|
148
157
|
|
|
149
|
-
${C.bold('
|
|
158
|
+
${C.bold('Atelier Library pull (1.2.x):')}
|
|
159
|
+
velinstyle atelier list
|
|
160
|
+
velinstyle atelier 36 [-o dir] [--format html|blade|vue|react] [--from <library>] [--base-url <url>]
|
|
161
|
+
Limitation: blade/vue/react = integration wrappers around vanilla assets (not native rewrites).
|
|
162
|
+
Native framework blocks / Velin Studio Builder = planned. Atelier ≠ Studio.
|
|
163
|
+
|
|
164
|
+
${C.bold('Plan / Review (1.2.x):')}
|
|
150
165
|
velinstyle plan "<prompt>" [--json] [-o plan.json]
|
|
166
|
+
velinstyle plan --atelier 04,07 [-o plan.json] Atelier compose plan (beta)
|
|
151
167
|
velinstyle review <file.html> [--json] [--prompt "..."]
|
|
152
168
|
|
|
169
|
+
${C.bold('Transparency (1.2.1):')}
|
|
170
|
+
velinstyle transparency doctor [path|file] [--policy file] [--json]
|
|
171
|
+
velinstyle transparency validate [path|file] [--policy file] [--json]
|
|
172
|
+
velinstyle transparency report [path|file] [--out dir] [--policy file]
|
|
173
|
+
velinstyle transparency export [path|file] [--format json|json-ld|csv|html] [-o file]
|
|
174
|
+
velinstyle transparency migrate [path|file] [--apply] [--write] [--policy file]
|
|
175
|
+
Alias: transparency scan → doctor
|
|
176
|
+
|
|
153
177
|
${C.bold('Layout (0.8.0):')}
|
|
154
178
|
velinstyle layout audit [path] Report flex/grid/responsive issues
|
|
155
179
|
velinstyle layout suggest [path] Audit with fix suggestions
|
|
@@ -160,6 +184,16 @@ function help() {
|
|
|
160
184
|
velinstyle perf suggest [path|file] Same as audit with fix hints
|
|
161
185
|
velinstyle perf fix [path|file] Apply safe fixes (--write)
|
|
162
186
|
|
|
187
|
+
${C.bold('Production Builder (1.2.2):')}
|
|
188
|
+
velinstyle build --production [path]
|
|
189
|
+
velinstyle production [path]
|
|
190
|
+
--out, -o <dir> Default: ./dist/velin-production
|
|
191
|
+
--explain Show removed CSS/themes/icons + reasons
|
|
192
|
+
--watch Rebuild on content change
|
|
193
|
+
--report <file> Write JSON/Markdown report
|
|
194
|
+
--safelist <list|file> Extra classes / themes / icons / CSS files
|
|
195
|
+
--no-js --no-icons --no-themes --no-motion --no-minify
|
|
196
|
+
|
|
163
197
|
${C.bold('Tokens:')}
|
|
164
198
|
velinstyle tokens build [--input <path>] [--output, -o <file>]
|
|
165
199
|
velinstyle tokens validate [--input <path>]
|
|
@@ -300,6 +334,13 @@ export default {
|
|
|
300
334
|
// ── Build ────────────────────────────────────────────────────────────────────
|
|
301
335
|
|
|
302
336
|
async function build() {
|
|
337
|
+
if (hasFlag('--production')) {
|
|
338
|
+
const { runProduction } = await import('./production/run.js');
|
|
339
|
+
const rest = args.slice(1).filter((a) => a !== '--production');
|
|
340
|
+
await runProduction({ args: rest, helpers: { getArg, hasFlag, C } });
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
303
344
|
const configPath = resolve('velinstyle.config.js');
|
|
304
345
|
let config;
|
|
305
346
|
|
|
@@ -777,6 +818,60 @@ async function prefixCmd() {
|
|
|
777
818
|
}
|
|
778
819
|
}
|
|
779
820
|
|
|
821
|
+
async function atelierCmd() {
|
|
822
|
+
const sub = args[1];
|
|
823
|
+
const {
|
|
824
|
+
listAtelierEntries,
|
|
825
|
+
pullAtelier,
|
|
826
|
+
} = await import('./atelier.js');
|
|
827
|
+
|
|
828
|
+
if (!sub || sub === '--help' || sub === '-h') {
|
|
829
|
+
console.log(`Usage: velinstyle atelier list
|
|
830
|
+
velinstyle atelier <num|id> [-o dir] [--format html|blade|vue|react]
|
|
831
|
+
[--from <library-root>] [--base-url <url>] [--rewrite-vendor <path>]
|
|
832
|
+
|
|
833
|
+
Pull a curated Atelier Library showcase (e.g. 36 → 36-calendar).
|
|
834
|
+
Limitation: --format blade|vue|react writes integration shells only (not native rewrites).
|
|
835
|
+
Velin Studio Builder and native framework blocks are planned — not shipped.`);
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (sub === 'list') {
|
|
840
|
+
const r = listAtelierEntries();
|
|
841
|
+
if (!r.ok) {
|
|
842
|
+
console.log(C.red(r.error));
|
|
843
|
+
process.exit(1);
|
|
844
|
+
}
|
|
845
|
+
console.log(`\n ${C.bold('Atelier Library (curated)')} · ${r.items.length} templates\n`);
|
|
846
|
+
for (const it of r.items) {
|
|
847
|
+
console.log(` ${C.cyan(it.num.padStart(3))} ${it.id} ${C.dim(it.title || '')}`);
|
|
848
|
+
}
|
|
849
|
+
console.log(`\n ${C.dim('Example: velinstyle atelier 36 -o ./velin-atelier/36-calendar')}\n`);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
const out = getArg('--output', '-o');
|
|
854
|
+
const format = getArg('--format') || 'html';
|
|
855
|
+
const from = getArg('--from') || process.env.VELINSTYLE_ATELIER_ROOT || null;
|
|
856
|
+
const baseUrl = getArg('--base-url');
|
|
857
|
+
const rewriteVendor = getArg('--rewrite-vendor');
|
|
858
|
+
|
|
859
|
+
const r = await pullAtelier(sub, {
|
|
860
|
+
output: out || undefined,
|
|
861
|
+
format,
|
|
862
|
+
from: from || undefined,
|
|
863
|
+
baseUrl: baseUrl || undefined,
|
|
864
|
+
rewriteVendor: rewriteVendor || undefined,
|
|
865
|
+
});
|
|
866
|
+
if (!r.ok) {
|
|
867
|
+
console.log(C.red(r.error));
|
|
868
|
+
process.exit(1);
|
|
869
|
+
}
|
|
870
|
+
console.log(C.green(`Pulled ${r.entry.id} → ${r.path} (format: ${r.format})`));
|
|
871
|
+
console.log(C.dim(` source: ${r.source}`));
|
|
872
|
+
console.log(C.dim(' Limitation: blade/vue/react = wrappers; Studio/native rewrites planned.'));
|
|
873
|
+
}
|
|
874
|
+
|
|
780
875
|
async function scaffoldCmd() {
|
|
781
876
|
const sub = args[1];
|
|
782
877
|
const { scaffoldFromPrompt, listIntents } = await import('./scaffold.js');
|
|
@@ -789,6 +884,38 @@ async function scaffoldCmd() {
|
|
|
789
884
|
console.log('');
|
|
790
885
|
return;
|
|
791
886
|
}
|
|
887
|
+
|
|
888
|
+
const atelierList = getArg('--atelier');
|
|
889
|
+
if (atelierList) {
|
|
890
|
+
const { composeAtelierPage } = await import('./atelier.js');
|
|
891
|
+
const out = getArg('--output', '-o') || resolve('velin-atelier/compose.html');
|
|
892
|
+
const from = getArg('--from') || process.env.VELINSTYLE_ATELIER_ROOT || null;
|
|
893
|
+
const baseUrl = getArg('--base-url');
|
|
894
|
+
const r = await composeAtelierPage(atelierList, {
|
|
895
|
+
output: out,
|
|
896
|
+
from: from || undefined,
|
|
897
|
+
baseUrl: baseUrl || undefined,
|
|
898
|
+
});
|
|
899
|
+
if (!r.ok) {
|
|
900
|
+
console.log(C.red(r.error));
|
|
901
|
+
process.exit(1);
|
|
902
|
+
}
|
|
903
|
+
if (hasFlag('--json')) {
|
|
904
|
+
console.log(JSON.stringify({
|
|
905
|
+
ok: true,
|
|
906
|
+
mode: r.mode,
|
|
907
|
+
path: r.path,
|
|
908
|
+
entries: r.entries,
|
|
909
|
+
planSections: r.planSections,
|
|
910
|
+
}, null, 2));
|
|
911
|
+
} else {
|
|
912
|
+
console.log(C.green(`Wrote Atelier compose (beta) → ${r.path}`));
|
|
913
|
+
console.log(C.dim(` ids: ${r.entries.map((e) => e.id).join(', ')}`));
|
|
914
|
+
console.log(C.dim(' Beta: Library compose — not Velin Studio. Wrappers ≠ native rewrites.'));
|
|
915
|
+
}
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
|
|
792
919
|
const promptParts = [];
|
|
793
920
|
let i = 1;
|
|
794
921
|
while (i < args.length) {
|
|
@@ -800,6 +927,7 @@ async function scaffoldCmd() {
|
|
|
800
927
|
const prompt = promptParts.join(' ').trim() || sub;
|
|
801
928
|
if (!prompt || prompt === 'list-intents') {
|
|
802
929
|
console.log('Usage: velinstyle scaffold "<description>" [-o file.html] [--json]');
|
|
930
|
+
console.log(' velinstyle scaffold --atelier 04,07 [-o page.html] [--from <library>]');
|
|
803
931
|
return;
|
|
804
932
|
}
|
|
805
933
|
const r = scaffoldFromPrompt(prompt);
|
|
@@ -826,6 +954,24 @@ async function scaffoldCmd() {
|
|
|
826
954
|
}
|
|
827
955
|
|
|
828
956
|
async function planCmd() {
|
|
957
|
+
const atelierList = getArg('--atelier');
|
|
958
|
+
if (atelierList) {
|
|
959
|
+
const { planFromAtelierList } = await import('./atelier.js');
|
|
960
|
+
const payload = planFromAtelierList(atelierList, { prompt: args.slice(1).filter((a) => !a.startsWith('-')).join(' ') });
|
|
961
|
+
if (!payload.ok) {
|
|
962
|
+
console.log(C.red(payload.error));
|
|
963
|
+
process.exit(1);
|
|
964
|
+
}
|
|
965
|
+
const out = getArg('--output', '-o');
|
|
966
|
+
if (out) {
|
|
967
|
+
writeFileSync(resolve(out), JSON.stringify(payload, null, 2), 'utf-8');
|
|
968
|
+
console.log(C.green(`Wrote Atelier plan (beta) ${resolve(out)} (${payload.plan.sections.length} sections)`));
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
|
|
829
975
|
const promptParts = [];
|
|
830
976
|
let i = 1;
|
|
831
977
|
while (i < args.length) {
|
|
@@ -837,6 +983,7 @@ async function planCmd() {
|
|
|
837
983
|
const prompt = promptParts.join(' ').trim();
|
|
838
984
|
if (!prompt) {
|
|
839
985
|
console.log('Usage: velinstyle plan "<description>" [--json] [-o plan.json]');
|
|
986
|
+
console.log(' velinstyle plan --atelier 04,07 [-o plan.json]');
|
|
840
987
|
return;
|
|
841
988
|
}
|
|
842
989
|
const { analyzePrompt, buildPlan } = await import('./prompt-engine.js');
|
|
@@ -877,7 +1024,10 @@ async function reviewCmd() {
|
|
|
877
1024
|
console.log(JSON.stringify(report, null, 2));
|
|
878
1025
|
} else {
|
|
879
1026
|
console.log(`\n ${C.bold('Review gate:')} ${report.gate} ${C.dim(`profile ${report.profile} · promptScore ${report.promptScore}`)}`);
|
|
880
|
-
console.log(C.dim(` design ${report.scores.design} · a11y ${report.scores.accessibility} · seo ${report.scores.seo} · perf ${report.scores.performance} · conversion ${report.scores.conversion}`));
|
|
1027
|
+
console.log(C.dim(` design ${report.scores.design} · a11y ${report.scores.accessibility} · seo ${report.scores.seo} · perf ${report.scores.performance} · conversion ${report.scores.conversion} · opt ${report.scores.optimization ?? '—'}`));
|
|
1028
|
+
if (report.optimization) {
|
|
1029
|
+
console.log(C.dim(` optimization · unused themes ${report.optimization.unusedThemes} · WC tags ${report.optimization.componentTags} · class tokens ${report.optimization.classTokens}`));
|
|
1030
|
+
}
|
|
881
1031
|
if (report.issues.length) {
|
|
882
1032
|
console.log(`\n ${C.bold('Issues:')}`);
|
|
883
1033
|
for (const issue of report.issues) {
|
|
@@ -1123,6 +1273,20 @@ async function checkCmd() {
|
|
|
1123
1273
|
steps.push({ step: 'review', ok: true, skipped: true });
|
|
1124
1274
|
}
|
|
1125
1275
|
|
|
1276
|
+
if (!quiet) console.log(C.bold('\n── transparency ──'));
|
|
1277
|
+
try {
|
|
1278
|
+
const { transparencyCheckStep } = await import('./transparency.js');
|
|
1279
|
+
const tx = await transparencyCheckStep(htmlFile || target, { quiet, C });
|
|
1280
|
+
if (!tx.ok && !tx.skipped) failed += 1;
|
|
1281
|
+
if (!quiet && tx.scores) {
|
|
1282
|
+
console.log(`Transparency ${tx.scores.transparency}% · AI ${tx.scores.ai}% · Trust ${tx.scores.trust}% · Provenance ${tx.scores.provenance}%`);
|
|
1283
|
+
}
|
|
1284
|
+
steps.push({ step: 'transparency', ok: tx.ok || !!tx.skipped, scores: tx.scores, skipped: tx.skipped });
|
|
1285
|
+
} catch (err) {
|
|
1286
|
+
if (!quiet) console.log(C.yellow(`transparency skipped: ${err.message}`));
|
|
1287
|
+
steps.push({ step: 'transparency', ok: true, skipped: true, error: String(err.message || err) });
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1126
1290
|
const payload = {
|
|
1127
1291
|
ok: failed === 0,
|
|
1128
1292
|
failedSteps: failed,
|
|
@@ -1181,8 +1345,8 @@ async function checkCmd() {
|
|
|
1181
1345
|
function suggestCommand(unknown) {
|
|
1182
1346
|
const names = [
|
|
1183
1347
|
'init', 'build', 'themes', 'add', 'icons', 'blueprint', 'create', 'serve', 'doctor', 'check',
|
|
1184
|
-
'validate', 'tokens', 'scan', 'prefix', 'scaffold', 'plan', 'review', 'layout', 'perf',
|
|
1185
|
-
'docs', 'documentation', 'meta', 'search', 'skills', 'workflow', 'wc',
|
|
1348
|
+
'validate', 'tokens', 'scan', 'prefix', 'scaffold', 'plan', 'review', 'transparency', 'layout', 'perf',
|
|
1349
|
+
'docs', 'documentation', 'meta', 'search', 'skills', 'workflow', 'wc', 'production', 'atelier',
|
|
1186
1350
|
];
|
|
1187
1351
|
const q = String(unknown || '').toLowerCase();
|
|
1188
1352
|
function editDistance(a, b) {
|
|
@@ -1229,7 +1393,12 @@ const resolvedCommand = ALIASES[command] || command;
|
|
|
1229
1393
|
|
|
1230
1394
|
switch (resolvedCommand) {
|
|
1231
1395
|
case 'init': init(); break;
|
|
1232
|
-
case 'build': build(); break;
|
|
1396
|
+
case 'build': await build(); break;
|
|
1397
|
+
case 'production': {
|
|
1398
|
+
const { runProduction } = await import('./production/run.js');
|
|
1399
|
+
await runProduction({ args: args.slice(1), helpers: { getArg, hasFlag, C } });
|
|
1400
|
+
break;
|
|
1401
|
+
}
|
|
1233
1402
|
case 'themes': themes(); break;
|
|
1234
1403
|
case 'add': add(); break;
|
|
1235
1404
|
case 'icons': icons(); break;
|
|
@@ -1243,7 +1412,13 @@ switch (resolvedCommand) {
|
|
|
1243
1412
|
case 'prefix': await prefixCmd(); break;
|
|
1244
1413
|
case 'scaffold': await scaffoldCmd(); break;
|
|
1245
1414
|
case 'plan': await planCmd(); break;
|
|
1415
|
+
case 'atelier': await atelierCmd(); break;
|
|
1246
1416
|
case 'review': await reviewCmd(); break;
|
|
1417
|
+
case 'transparency': {
|
|
1418
|
+
const { transparencyCmd } = await import('./transparency.js');
|
|
1419
|
+
await transparencyCmd(args.slice(1), { C, getArg, hasFlag });
|
|
1420
|
+
break;
|
|
1421
|
+
}
|
|
1247
1422
|
case 'layout': await layoutCmd(); break;
|
|
1248
1423
|
case 'perf': await perfCmd(); break;
|
|
1249
1424
|
case 'docs': await docsCmd(); break;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"alwaysCss": [
|
|
4
|
+
"tokens/fonts.css",
|
|
5
|
+
"tokens/color.css",
|
|
6
|
+
"tokens/spacing.css",
|
|
7
|
+
"tokens/typography.css",
|
|
8
|
+
"tokens/radius.css",
|
|
9
|
+
"tokens/shadow.css",
|
|
10
|
+
"tokens/motion.css",
|
|
11
|
+
"tokens/z-index.css",
|
|
12
|
+
"tokens/aspect-ratio.css",
|
|
13
|
+
"base/root.css",
|
|
14
|
+
"base/reset.css",
|
|
15
|
+
"base/focus.css",
|
|
16
|
+
"base/content.css",
|
|
17
|
+
"a11y/sr-only.css",
|
|
18
|
+
"a11y/skip-link.css",
|
|
19
|
+
"a11y/reduced-motion.css",
|
|
20
|
+
"a11y/forced-colors.css",
|
|
21
|
+
"a11y/focus-appearance.css",
|
|
22
|
+
"a11y/target-size.css",
|
|
23
|
+
"layout/breakpoints.css",
|
|
24
|
+
"layout/container.css"
|
|
25
|
+
],
|
|
26
|
+
"classPrefixes": {
|
|
27
|
+
"velin-btn": { "css": ["components/button.css"] },
|
|
28
|
+
"velin-card": { "css": ["components/card.css"] },
|
|
29
|
+
"velin-input": { "css": ["components/input.css", "components/form-validation.css"] },
|
|
30
|
+
"velin-textarea": { "css": ["components/input.css", "components/form-validation.css"] },
|
|
31
|
+
"velin-select": { "css": ["components/input.css", "components/form-validation.css"] },
|
|
32
|
+
"velin-label": { "css": ["components/input.css"] },
|
|
33
|
+
"velin-field": { "css": ["components/input.css", "components/form-validation.css"] },
|
|
34
|
+
"velin-nav": { "css": ["components/nav.css"] },
|
|
35
|
+
"velin-navbar": { "css": ["components/nav.css"] },
|
|
36
|
+
"velin-alert": { "css": ["components/alert.css"] },
|
|
37
|
+
"velin-badge": { "css": ["components/badge.css"] },
|
|
38
|
+
"velin-table": { "css": ["components/table.css"] },
|
|
39
|
+
"velin-data-table": { "css": ["components/data-table.css", "components/table.css"] },
|
|
40
|
+
"velin-tooltip": { "css": ["components/tooltip.css"] },
|
|
41
|
+
"velin-modal": { "css": ["components/modal.css", "components/button.css"] },
|
|
42
|
+
"velin-dialog": { "css": ["components/modal.css", "components/button.css"] },
|
|
43
|
+
"velin-breadcrumb": { "css": ["components/breadcrumb.css"] },
|
|
44
|
+
"velin-pagination": { "css": ["components/pagination.css"] },
|
|
45
|
+
"velin-progress": { "css": ["components/progress.css"] },
|
|
46
|
+
"velin-spinner": { "css": ["components/spinner.css"] },
|
|
47
|
+
"velin-list": { "css": ["components/list-group.css"] },
|
|
48
|
+
"velin-avatar": { "css": ["components/avatar.css"] },
|
|
49
|
+
"velin-switch": { "css": ["components/switch.css"] },
|
|
50
|
+
"velin-divider": { "css": ["components/divider.css"] },
|
|
51
|
+
"velin-chip": { "css": ["components/chip.css"] },
|
|
52
|
+
"velin-timeline": { "css": ["components/timeline.css"] },
|
|
53
|
+
"velin-stepper": { "css": ["components/stepper.css"] },
|
|
54
|
+
"velin-stat": { "css": ["components/stat.css"] },
|
|
55
|
+
"velin-drawer": { "css": ["components/drawer.css", "components/button.css"] },
|
|
56
|
+
"velin-sheet": { "css": ["components/drawer.css", "components/button.css"] },
|
|
57
|
+
"velin-input-group": { "css": ["components/input-group.css", "components/input.css"] },
|
|
58
|
+
"velin-collapse": { "css": ["components/collapse.css"] },
|
|
59
|
+
"velin-accordion": { "css": ["components/collapse.css"] },
|
|
60
|
+
"velin-calendar": { "css": ["components/calendar-dropzone.css"] },
|
|
61
|
+
"velin-dropzone": { "css": ["components/calendar-dropzone.css"] },
|
|
62
|
+
"velin-grid": { "css": ["layout/grid.css"] },
|
|
63
|
+
"velin-flex": { "css": ["layout/flex.css"] },
|
|
64
|
+
"velin-container": { "css": ["layout/container.css"] },
|
|
65
|
+
"velin-stack": { "css": ["layout/patterns.css"] },
|
|
66
|
+
"velin-cluster": { "css": ["layout/patterns.css"] },
|
|
67
|
+
"velin-sidebar": { "css": ["layout/patterns.css", "layout/app-shell.css"] },
|
|
68
|
+
"velin-app": { "css": ["layout/app-shell.css"] },
|
|
69
|
+
"velin-shell": { "css": ["layout/app-shell.css"] },
|
|
70
|
+
"velin-skeleton": { "css": ["a11y/skeleton.css"] },
|
|
71
|
+
"velin-sr-only": { "css": ["a11y/sr-only.css"] },
|
|
72
|
+
"velin-skip": { "css": ["a11y/skip-link.css"] },
|
|
73
|
+
"velin-transparency": { "css": ["components/transparency.css"] },
|
|
74
|
+
"velin-disclosure": { "css": ["components/transparency.css"] },
|
|
75
|
+
"velin-otp-input": { "css": ["components/empty-auth.css", "components/input.css"] },
|
|
76
|
+
"velin-password-strength": { "css": ["components/empty-auth.css", "components/progress.css"] },
|
|
77
|
+
"velin-empty-state": { "css": ["components/empty-auth.css", "components/button.css"] }
|
|
78
|
+
},
|
|
79
|
+
"wc": {
|
|
80
|
+
"velin-modal": { "css": ["components/modal.css", "components/button.css"], "peers": ["velin-icon"] },
|
|
81
|
+
"velin-dialog": { "css": ["components/modal.css", "components/button.css"], "peers": ["velin-icon"] },
|
|
82
|
+
"velin-drawer": { "css": ["components/drawer.css", "components/button.css"], "peers": [] },
|
|
83
|
+
"velin-sheet": { "css": ["components/drawer.css", "components/button.css"], "peers": [] },
|
|
84
|
+
"velin-toast": { "css": ["components/alert.css"], "peers": ["velin-icon"] },
|
|
85
|
+
"velin-tooltip": { "css": ["components/tooltip.css"], "peers": [] },
|
|
86
|
+
"velin-tooltip-wc": { "css": ["components/tooltip.css"], "peers": [] },
|
|
87
|
+
"velin-tabs": { "css": ["components/nav.css"], "peers": [] },
|
|
88
|
+
"velin-icon": { "css": [], "peers": [] },
|
|
89
|
+
"velin-accordion": { "css": ["components/collapse.css"], "peers": [] },
|
|
90
|
+
"velin-collapse": { "css": ["components/collapse.css"], "peers": [] },
|
|
91
|
+
"velin-dropdown": { "css": ["components/nav.css", "components/button.css"], "peers": [] },
|
|
92
|
+
"velin-popover": { "css": ["components/tooltip.css"], "peers": [] },
|
|
93
|
+
"velin-carousel": { "css": [], "peers": ["velin-icon"] },
|
|
94
|
+
"velin-lightbox": { "css": ["components/modal.css"], "peers": ["velin-icon"] },
|
|
95
|
+
"velin-data-table": { "css": ["components/data-table.css", "components/table.css"], "peers": [] },
|
|
96
|
+
"velin-stepper": { "css": ["components/stepper.css"], "peers": [] },
|
|
97
|
+
"velin-stepper-wc": { "css": ["components/stepper.css"], "peers": [] },
|
|
98
|
+
"velin-theme-toggle": { "css": ["components/button.css"], "peers": ["velin-icon"] },
|
|
99
|
+
"velin-search": { "css": ["components/input.css", "components/input-group.css"], "peers": ["velin-icon"] },
|
|
100
|
+
"velin-combobox": { "css": ["components/input.css"], "peers": [] },
|
|
101
|
+
"velin-command": { "css": ["components/modal.css", "components/input.css"], "peers": [] },
|
|
102
|
+
"velin-bottom-nav": { "css": ["components/nav.css"], "peers": ["velin-icon"] },
|
|
103
|
+
"velin-menubar": { "css": ["components/nav.css"], "peers": [] },
|
|
104
|
+
"velin-calendar": { "css": ["components/calendar-dropzone.css"], "peers": [] },
|
|
105
|
+
"velin-file-dropzone": { "css": ["components/calendar-dropzone.css"], "peers": [] },
|
|
106
|
+
"velin-progress-ring": { "css": ["components/progress.css"], "peers": [] },
|
|
107
|
+
"velin-rating": { "css": ["components/chip.css"], "peers": ["velin-icon"] },
|
|
108
|
+
"velin-scroll-top": { "css": ["components/button.css"], "peers": ["velin-icon"] },
|
|
109
|
+
"velin-scrollspy": { "css": [], "peers": [] },
|
|
110
|
+
"velin-sparkline": { "css": [], "peers": [] },
|
|
111
|
+
"velin-countdown": { "css": ["components/stat.css"], "peers": [] },
|
|
112
|
+
"velin-counter": { "css": ["components/stat.css"], "peers": [] },
|
|
113
|
+
"velin-live-dot": { "css": ["components/badge.css"], "peers": [] },
|
|
114
|
+
"velin-announcer": { "css": ["a11y/sr-only.css"], "peers": [] },
|
|
115
|
+
"velin-copy": { "css": ["components/button.css"], "peers": ["velin-icon"] },
|
|
116
|
+
"velin-email": { "css": ["components/input.css"], "peers": [] },
|
|
117
|
+
"velin-secure-field": { "css": ["components/input.css", "a11y/security.css"], "peers": [] },
|
|
118
|
+
"velin-form-summary": { "css": ["components/form-validation.css", "components/alert.css"], "peers": [] },
|
|
119
|
+
"velin-persist": { "css": [], "peers": [] },
|
|
120
|
+
"velin-code-block": { "css": [], "peers": [] },
|
|
121
|
+
"velin-segmented-control": { "css": ["components/chip.css", "components/button.css"], "peers": [] },
|
|
122
|
+
"velin-otp-input": { "css": ["components/empty-auth.css", "components/input.css"], "peers": [] },
|
|
123
|
+
"velin-password-strength": { "css": ["components/empty-auth.css", "components/progress.css"], "peers": [] },
|
|
124
|
+
"velin-empty-state": { "css": ["components/empty-auth.css", "components/button.css"], "peers": [] }
|
|
125
|
+
},
|
|
126
|
+
"utilityFiles": [
|
|
127
|
+
"utilities/color.css",
|
|
128
|
+
"utilities/spacing.css",
|
|
129
|
+
"utilities/display.css",
|
|
130
|
+
"utilities/text.css",
|
|
131
|
+
"utilities/sizing.css",
|
|
132
|
+
"utilities/border.css",
|
|
133
|
+
"utilities/position.css",
|
|
134
|
+
"utilities/animation.css",
|
|
135
|
+
"utilities/gradient.css",
|
|
136
|
+
"utilities/print.css",
|
|
137
|
+
"utilities/responsive.css",
|
|
138
|
+
"utilities/divide.css",
|
|
139
|
+
"utilities/scroll.css",
|
|
140
|
+
"utilities/color-mix.css",
|
|
141
|
+
"utilities/scroll-animation.css",
|
|
142
|
+
"utilities/view-transition.css",
|
|
143
|
+
"utilities/scope.css",
|
|
144
|
+
"utilities/anchor.css",
|
|
145
|
+
"utilities/filter.css",
|
|
146
|
+
"utilities/filter-effects.css",
|
|
147
|
+
"utilities/chart-animation.css",
|
|
148
|
+
"utilities/container-style.css",
|
|
149
|
+
"utilities/state.css",
|
|
150
|
+
"utilities/safe-area.css"
|
|
151
|
+
],
|
|
152
|
+
"motionFiles": [
|
|
153
|
+
"utilities/animation.css",
|
|
154
|
+
"utilities/scroll-animation.css",
|
|
155
|
+
"utilities/chart-animation.css",
|
|
156
|
+
"utilities/view-transition.css",
|
|
157
|
+
"tokens/motion.css",
|
|
158
|
+
"a11y/reduced-motion.css"
|
|
159
|
+
],
|
|
160
|
+
"fontClassPrefixes": [
|
|
161
|
+
"velin-font-",
|
|
162
|
+
"velin-text-",
|
|
163
|
+
"velin-leading-",
|
|
164
|
+
"velin-tracking-"
|
|
165
|
+
]
|
|
166
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --explain: human-readable removals with reasons.
|
|
3
|
+
*/
|
|
4
|
+
export function buildExplain({
|
|
5
|
+
skippedCss = [],
|
|
6
|
+
skippedThemes = [],
|
|
7
|
+
skippedIcons = [],
|
|
8
|
+
skippedMotion = false,
|
|
9
|
+
graphExplain = [],
|
|
10
|
+
} = {}) {
|
|
11
|
+
const removed = [];
|
|
12
|
+
|
|
13
|
+
for (const item of skippedCss) {
|
|
14
|
+
removed.push({
|
|
15
|
+
id: item.file || item,
|
|
16
|
+
reason: item.reason || 'Nicht benutzt',
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
for (const theme of skippedThemes) {
|
|
20
|
+
removed.push({ id: `${theme}.theme.css`, reason: 'Nicht benutzt' });
|
|
21
|
+
}
|
|
22
|
+
for (const icon of skippedIcons.slice(0, 40)) {
|
|
23
|
+
removed.push({ id: `icon:${icon}`, reason: 'Nicht benutzt' });
|
|
24
|
+
}
|
|
25
|
+
if (skippedIcons.length > 40) {
|
|
26
|
+
removed.push({ id: `icon:…(+${skippedIcons.length - 40})`, reason: 'Nicht benutzt' });
|
|
27
|
+
}
|
|
28
|
+
if (skippedMotion) {
|
|
29
|
+
removed.push({ id: 'motion utilities', reason: 'Keine Animate-/Motion-Klassen gefunden' });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const kept = [];
|
|
33
|
+
const seen = new Set();
|
|
34
|
+
for (const e of graphExplain) {
|
|
35
|
+
if (!e.keep || seen.has(e.keep)) continue;
|
|
36
|
+
seen.add(e.keep);
|
|
37
|
+
kept.push({ id: e.keep, reason: e.reason });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const lines = ['Entfernt'];
|
|
41
|
+
if (!removed.length) lines.push('(nichts entfernt — oder Scan fand fast alles)');
|
|
42
|
+
for (const r of removed) {
|
|
43
|
+
lines.push(`${r.id.padEnd(28)} ${r.reason}`);
|
|
44
|
+
}
|
|
45
|
+
lines.push('');
|
|
46
|
+
lines.push('Behalten (Auszug)');
|
|
47
|
+
for (const k of kept.slice(0, 30)) {
|
|
48
|
+
lines.push(`${k.id.padEnd(28)} ${k.reason}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { removed, kept, text: lines.join('\n') };
|
|
52
|
+
}
|