@birdapi/velinstyle 1.2.2 → 1.3.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.
Files changed (109) hide show
  1. package/README.de.md +18 -4
  2. package/README.md +42 -7
  3. package/cli/cli-manifest.json +441 -174
  4. package/cli/docgen/extract-cli.js +2 -1
  5. package/cli/docs-generate.js +9 -0
  6. package/cli/experience.js +173 -0
  7. package/cli/index.js +1294 -417
  8. package/cli/motion.js +738 -0
  9. package/cli/production/extract.js +46 -6
  10. package/cli/production/report.js +104 -14
  11. package/cli/production/run.js +44 -1
  12. package/cli/security.js +190 -0
  13. package/cli/skills.js +53 -10
  14. package/cli/transparency.js +140 -41
  15. package/cli/workflow.js +32 -17
  16. package/components/velin-theme-toggle.js +15 -1
  17. package/core/a11y/component-contracts.json +391 -274
  18. package/core/attributes/registry.js +1 -1
  19. package/core/motion/analyze.js +38 -0
  20. package/core/motion/blueprint.js +51 -0
  21. package/core/motion/composer.js +114 -0
  22. package/core/motion/data/registry.json +352 -0
  23. package/core/motion/effects.js +17 -1
  24. package/core/motion/index.js +112 -9
  25. package/core/motion/optimize.js +44 -0
  26. package/core/motion/policy.js +77 -0
  27. package/core/motion/registry.js +131 -0
  28. package/core/motion/review.js +59 -0
  29. package/core/motion/scan.js +150 -0
  30. package/core/motion/timeline.js +68 -0
  31. package/core/motion/transitions.js +49 -0
  32. package/core/motion/triggers.js +168 -0
  33. package/core/security/checks/fs.js +92 -0
  34. package/core/security/detect.js +35 -0
  35. package/core/security/engine.js +116 -0
  36. package/core/security/index.js +18 -0
  37. package/core/security/registry.js +85 -0
  38. package/core/security/report/report.js +113 -0
  39. package/core/security/rules/ci/index.js +146 -0
  40. package/core/security/rules/consumer/index.js +174 -0
  41. package/core/security/rules/deps/index.js +182 -0
  42. package/core/security/rules/index.js +24 -0
  43. package/core/security/rules/publish/index.js +230 -0
  44. package/core/security/rules/repo/index.js +143 -0
  45. package/core/security/rules/secrets/index.js +133 -0
  46. package/core/security/score/dependency-health.js +53 -0
  47. package/core/security/score/release-health.js +66 -0
  48. package/core/security/score/score.js +102 -0
  49. package/core/security/timeline/timeline.js +76 -0
  50. package/dist/chunks/attributes-HK7VIOLA.js +1080 -0
  51. package/dist/chunks/attributes-VRHHVNDO.js +1080 -0
  52. package/dist/chunks/chunk-MYKUI364.js +116 -0
  53. package/dist/chunks/chunk-NEVBPD5T.js +116 -0
  54. package/dist/chunks/runtime-entry.js +1 -1
  55. package/dist/chunks/velin-theme-toggle-J2NHC7IM.js +304 -0
  56. package/dist/llms.txt +2 -2
  57. package/dist/search-index.json +166 -2
  58. package/dist/velin-agent.json +156 -32
  59. package/dist/velinstyle-components.iife.js +862 -17
  60. package/dist/velinstyle-components.js +862 -17
  61. package/dist/velinstyle-components.min.js +126 -126
  62. package/dist/velinstyle.css +42 -7
  63. package/dist/velinstyle.min.css +1 -1
  64. package/package.json +158 -143
  65. package/packages/velinstyle-cli-core/package.json +11 -0
  66. package/packages/velinstyle-cli-core/src/config.js +84 -0
  67. package/packages/velinstyle-cli-core/src/contract.js +56 -0
  68. package/packages/velinstyle-cli-core/src/event-bus.js +50 -0
  69. package/packages/velinstyle-cli-core/src/index.js +18 -0
  70. package/packages/velinstyle-cli-core/src/lifecycle.js +33 -0
  71. package/packages/velinstyle-cli-core/src/runner.js +129 -0
  72. package/packages/velinstyle-cli-registry/data/commands.json +1216 -0
  73. package/packages/velinstyle-cli-registry/data/layouts.json +33 -0
  74. package/packages/velinstyle-cli-registry/data/widgets.json +35 -0
  75. package/packages/velinstyle-cli-registry/package.json +13 -0
  76. package/packages/velinstyle-cli-registry/src/index.js +88 -0
  77. package/packages/velinstyle-cli-renderer/package.json +8 -0
  78. package/packages/velinstyle-cli-renderer/src/index.js +286 -0
  79. package/packages/velinstyle-cli-theme/package.json +8 -0
  80. package/packages/velinstyle-cli-theme/src/index.js +84 -0
  81. package/packages/velinstyle-cli-ui/package.json +8 -0
  82. package/packages/velinstyle-cli-ui/src/index.js +34 -0
  83. package/packages/velinstyle-motion/README.md +81 -0
  84. package/packages/velinstyle-motion/package.json +37 -0
  85. package/packages/velinstyle-motion/src/ai/mini-prompt.js +119 -0
  86. package/packages/velinstyle-motion/src/ai/provider.js +59 -0
  87. package/packages/velinstyle-motion/src/ai/providers/pixverse-setup.js +402 -0
  88. package/packages/velinstyle-motion/src/ai/providers/pixverse.js +245 -0
  89. package/packages/velinstyle-motion/src/config.js +257 -0
  90. package/packages/velinstyle-motion/src/export/html-clip.js +141 -0
  91. package/packages/velinstyle-motion/src/index.js +304 -0
  92. package/packages/velinstyle-motion/src/jobs/cache.js +30 -0
  93. package/packages/velinstyle-motion/src/jobs/queue.js +69 -0
  94. package/packages/velinstyle-motion/src/jobs/usage.js +53 -0
  95. package/packages/velinstyle-motion/src/local/effects.js +139 -0
  96. package/packages/velinstyle-motion/src/local/engine.js +96 -0
  97. package/packages/velinstyle-motion/src/providers-catalog.js +44 -0
  98. package/packages/velinstyle-motion/src/registry/presets.js +25 -0
  99. package/packages/velinstyle-motion/src/registry/presets.json +85 -0
  100. package/packages/velinstyle-motion/src/ux/cost-gate.js +37 -0
  101. package/packages/velinstyle-motion/src/ux/pixverse-gate.js +153 -0
  102. package/packages/velinstyle-motion/src/ux/wizard.js +171 -0
  103. package/packages/velinstyle-motion/src/validate-image.js +91 -0
  104. package/packages/velinstyle-skills/catalog.json +1 -1
  105. package/packages/velinstyle-skills/registry.json +1 -142
  106. package/packages/velinstyle-skills/skills/velin-motion-reduced-safe/SKILL.md +1 -1
  107. package/packages/velinstyle-skills/skills/velin-motion-reveal-feedback/SKILL.md +1 -1
  108. package/src/tokens/motion.css +7 -0
  109. package/src/utilities/scroll-animation.css +66 -0
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Aggregate Security Engine findings into category scores + overall.
3
+ */
4
+
5
+ const SEV_WEIGHT = { error: 18, warning: 8, info: 2 };
6
+
7
+ /**
8
+ * @param {import('../registry.js').SecurityFinding[]} findings
9
+ */
10
+ export function scoreFindings(findings) {
11
+ const byCat = {};
12
+ for (const f of findings) {
13
+ const cat = f.code || f.category || 'repo';
14
+ // findings carry rule category via ruleId prefix or explicit
15
+ }
16
+
17
+ const categories = {
18
+ supplyChain: { label: 'Supply Chain', findings: [] },
19
+ secrets: { label: 'Secrets', findings: [] },
20
+ dependencies: { label: 'Dependencies', findings: [] },
21
+ publish: { label: 'Publish', findings: [] },
22
+ ci: { label: 'CI', findings: [] },
23
+ workflows: { label: 'Workflows', findings: [] },
24
+ malware: { label: 'Malware', findings: [] },
25
+ repo: { label: 'Repository', findings: [] },
26
+ consumer: { label: 'Consumer', findings: [] },
27
+ };
28
+
29
+ for (const f of findings) {
30
+ const cat = mapFindingCategory(f);
31
+ if (!categories[cat]) categories[cat] = { label: cat, findings: [] };
32
+ categories[cat].findings.push(f);
33
+ }
34
+
35
+ /** @type {Record<string, { score: number, gate: string, label: string, count: number }>} */
36
+ const scores = {};
37
+ let totalDeduction = 0;
38
+ let errorCount = 0;
39
+
40
+ for (const [key, bucket] of Object.entries(categories)) {
41
+ let ded = 0;
42
+ for (const f of bucket.findings) {
43
+ ded += SEV_WEIGHT[f.severity] || 4;
44
+ if (f.severity === 'error') errorCount += 1;
45
+ }
46
+ ded = Math.min(100, ded);
47
+ const score = Math.max(0, 100 - ded);
48
+ const gate = gateFromFindings(bucket.findings);
49
+ if (key === 'malware' && bucket.findings.length === 0) {
50
+ scores[key] = {
51
+ score: null,
52
+ na: true,
53
+ gate: 'pass',
54
+ label: bucket.label,
55
+ count: 0,
56
+ note: 'no malware rules fired',
57
+ };
58
+ } else {
59
+ scores[key] = { score, gate, label: bucket.label, count: bucket.findings.length };
60
+ totalDeduction += ded * 0.12;
61
+ }
62
+ }
63
+
64
+ const securityScore = Math.max(0, Math.min(100, Math.round(100 - totalDeduction)));
65
+ const overallGate = errorCount > 0 ? 'fail' : Object.values(scores).some((s) => s.gate === 'warn') ? 'warn' : 'pass';
66
+ const overall = overallGate === 'fail' ? 'BLOCKED' : overallGate === 'warn' ? 'READY_WITH_WARNINGS' : 'READY';
67
+
68
+ return { securityScore, scores, overall, overallGate, findings };
69
+ }
70
+
71
+ function mapFindingCategory(f) {
72
+ if (f.category) {
73
+ if (f.category === 'deps') return 'dependencies';
74
+ if (f.category === 'ci') return 'ci';
75
+ if (f.category === 'secrets') return 'secrets';
76
+ if (f.category === 'publish') return 'publish';
77
+ if (f.category === 'malware') return 'malware';
78
+ if (f.category === 'consumer') return 'consumer';
79
+ if (f.category === 'repo') return 'repo';
80
+ }
81
+ const id = f.ruleId || '';
82
+ if (id.startsWith('secrets.') || id.startsWith('secret.')) return 'secrets';
83
+ if (id === 'deps.lifecycle-hooks' || id === 'deps.typosquat' || id.startsWith('malware.')) return 'malware';
84
+ if (id.startsWith('deps.') || id.startsWith('dependency.')) return 'dependencies';
85
+ if (id.startsWith('workflow.') || id.startsWith('ci.')) return 'ci';
86
+ if (id.startsWith('publish.') || id.startsWith('release.')) return 'publish';
87
+ if (id.startsWith('consumer.')) return 'consumer';
88
+ if (id.includes('supply') || id.startsWith('lockfile') || id.startsWith('lifecycle')) return 'supplyChain';
89
+ return 'repo';
90
+ }
91
+
92
+ function gateFromFindings(findings) {
93
+ if (findings.some((f) => f.severity === 'error')) return 'fail';
94
+ if (findings.some((f) => f.severity === 'warning')) return 'warn';
95
+ return 'pass';
96
+ }
97
+
98
+ export function gateLabel(gate) {
99
+ if (gate === 'fail') return 'FAIL';
100
+ if (gate === 'warn') return 'WARNING';
101
+ return 'PASS';
102
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Security Timeline — local last-run stamps.
3
+ */
4
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
5
+ import { dirname, join } from 'path';
6
+
7
+ const CATEGORIES = ['repository', 'dependencies', 'publish', 'ci', 'secrets', 'consumer', 'audit'];
8
+
9
+ /**
10
+ * @param {string} root
11
+ */
12
+ export function timelinePath(root) {
13
+ return join(root, '.velin', 'security', 'timeline.json');
14
+ }
15
+
16
+ /**
17
+ * @param {string} root
18
+ */
19
+ export function loadTimeline(root) {
20
+ const p = timelinePath(root);
21
+ if (!existsSync(p)) {
22
+ return { version: 1, entries: {} };
23
+ }
24
+ try {
25
+ return JSON.parse(readFileSync(p, 'utf-8'));
26
+ } catch {
27
+ return { version: 1, entries: {} };
28
+ }
29
+ }
30
+
31
+ /**
32
+ * @param {string} root
33
+ * @param {string[]} categories
34
+ * @param {Date} [when]
35
+ */
36
+ export function touchTimeline(root, categories, when = new Date()) {
37
+ const data = loadTimeline(root);
38
+ const iso = when.toISOString();
39
+ const dateLabel = when.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
40
+ for (const c of categories) {
41
+ const key = normalizeCat(c);
42
+ data.entries[key] = { at: iso, label: dateLabel };
43
+ }
44
+ const p = timelinePath(root);
45
+ mkdirSync(dirname(p), { recursive: true });
46
+ writeFileSync(p, `${JSON.stringify(data, null, 2)}\n`, 'utf-8');
47
+ return data;
48
+ }
49
+
50
+ function normalizeCat(c) {
51
+ if (c === 'repo') return 'repository';
52
+ if (c === 'deps') return 'dependencies';
53
+ return c;
54
+ }
55
+
56
+ /**
57
+ * Rows for Experience / report.
58
+ * @param {ReturnType<typeof loadTimeline>} data
59
+ */
60
+ export function timelineRows(data) {
61
+ const labels = {
62
+ repository: 'Repository geprüft',
63
+ dependencies: 'Dependencies geprüft',
64
+ publish: 'Publish geprüft',
65
+ ci: 'CI geprüft',
66
+ secrets: 'Secrets geprüft',
67
+ consumer: 'Consumer geprüft',
68
+ audit: 'Audit geprüft',
69
+ };
70
+ return CATEGORIES.filter((k) => data.entries?.[k]).map((k) => ({
71
+ key: k,
72
+ title: labels[k] || k,
73
+ date: data.entries[k].label || data.entries[k].at?.slice(0, 10),
74
+ at: data.entries[k].at,
75
+ }));
76
+ }