@birdapi/velinstyle 1.1.0 → 1.2.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.de.md +87 -162
- package/README.md +188 -119
- package/cli/blueprint.js +98 -5
- package/cli/blueprints/app-chrome.html +18 -0
- package/cli/blueprints/benefits-grid.html +9 -0
- package/cli/blueprints/bottom-nav-mobile.html +2 -1
- package/cli/blueprints/cookie-consent.html +1 -1
- package/cli/blueprints/cta-band.html +6 -0
- package/cli/blueprints/faq-section.html +18 -0
- package/cli/blueprints/filter-bar.html +4 -4
- package/cli/blueprints/form-contact.html +6 -5
- package/cli/blueprints/hero-section.html +3 -3
- package/cli/blueprints/notification-center.html +1 -1
- package/cli/blueprints/onboarding.html +2 -1
- package/cli/blueprints/ops-console.html +29 -0
- package/cli/blueprints/pricing-band.html +37 -0
- package/cli/blueprints/process-steps.html +10 -0
- package/cli/blueprints/services-grid.html +9 -0
- package/cli/blueprints/settings-panel.html +8 -6
- package/cli/blueprints/split-hero.html +25 -0
- package/cli/blueprints/testimonials.html +8 -0
- package/cli/blueprints/trust-bar.html +10 -0
- package/cli/cli-manifest.json +81 -17
- package/cli/contrast-utils.js +97 -0
- package/cli/create.js +370 -0
- package/cli/docgen/extract-attributes.js +126 -10
- package/cli/docgen/extract-cli.js +3 -2
- package/cli/docgen/extract-components.js +61 -2
- package/cli/docgen/extract-utilities.js +10 -10
- package/cli/doctor.js +119 -0
- package/cli/index.js +531 -44
- package/cli/meta.js +84 -1
- package/cli/perf-audit.js +15 -2
- package/cli/prompt-engine.js +243 -0
- package/cli/review.js +268 -0
- package/cli/scaffold.js +119 -4
- package/cli/scanner-rules-data.js +7 -0
- package/cli/scanner.js +357 -4
- package/cli/serve.js +81 -0
- package/cli/skills.js +223 -0
- package/cli/wc-api.js +89 -0
- package/cli/workflow.js +42 -0
- package/components/index.js +2 -0
- package/components/runtime/component-loaders.js +2 -0
- package/components/velin-accordion.js +62 -13
- package/components/velin-bottom-nav.js +10 -0
- package/components/velin-calendar.js +212 -0
- package/components/velin-command.js +18 -2
- package/components/velin-data-table.js +78 -1
- package/components/velin-dialog.js +4 -1
- package/components/velin-drawer.js +2 -4
- package/components/velin-file-dropzone.js +162 -0
- package/components/velin-icon.js +22 -1
- package/components/velin-lightbox.js +5 -3
- package/components/velin-modal.js +2 -4
- package/components/velin-search.js +1 -1
- package/components/velin-sheet.js +2 -4
- package/core/a11y/component-contracts.json +20 -3
- package/core/meta/build.js +125 -5
- package/core/meta/design-constraints/contact.json +9 -0
- package/core/meta/design-constraints/faq.json +9 -0
- package/core/meta/design-constraints/hero.json +13 -0
- package/core/meta/knowledge/components.json +622 -0
- package/core/meta/knowledge/tokens.json +282 -0
- package/core/meta/pages/registry.json +294 -0
- package/core/meta/schema.js +3 -1
- package/core/meta/sections/registry.json +185 -0
- package/dist/chunks/{attributes-STYCS3O5.js → attributes-A423NX5J.js} +3 -3
- package/dist/chunks/{attributes-353XDOAX.js → attributes-F6UPIEVP.js} +1 -1
- package/dist/chunks/{attributes-ADOKLKA7.js → attributes-GLYXGGAL.js} +3 -3
- package/dist/chunks/{attributes-TPANLMLF.js → attributes-UFTYOSAU.js} +3 -3
- package/dist/chunks/attributes-XGLXLR2T.js +391 -0
- package/dist/chunks/attributes-YF4NI2QS.js +391 -0
- package/dist/chunks/browser-AUABBYUK.js +1544 -0
- package/dist/chunks/{chunk-RSMRR27R.js → chunk-2LSKX57P.js} +12 -10
- package/dist/chunks/{chunk-IEHKRARD.js → chunk-2TGCVDUL.js} +11 -9
- package/dist/chunks/{chunk-SRL6EWHP.js → chunk-5JWGUAPC.js} +17 -13
- package/dist/chunks/chunk-7YSO2OQ2.js +113 -0
- package/dist/chunks/{chunk-QVHYL3R4.js → chunk-BHR3ZG6U.js} +6 -6
- package/dist/chunks/{chunk-J472ERN2.js → chunk-JMSIHEYX.js} +15 -4
- package/dist/chunks/{chunk-MKZP2TBH.js → chunk-L7ZGUU4D.js} +2 -2
- package/dist/chunks/chunk-TUGIPKW5.js +113 -0
- package/dist/chunks/{highlight-GJHHV4KM.js → highlight-M2ELQNYK.js} +1 -1
- package/dist/chunks/runtime-entry.js +1 -1
- package/dist/chunks/{velin-accordion-FBIPAEXG.js → velin-accordion-WSY6BMLA.js} +64 -10
- package/dist/chunks/{velin-bottom-nav-7GEMPIM6.js → velin-bottom-nav-5RVRNGIP.js} +25 -0
- package/dist/chunks/{velin-bottom-nav-N3DFQR66.js → velin-bottom-nav-N5F4UO2I.js} +26 -1
- package/dist/chunks/velin-calendar-OFE6THUD.js +210 -0
- package/dist/chunks/velin-calendar-PGVNJTXK.js +217 -0
- package/dist/chunks/velin-calendar-XC7JRDSH.js +217 -0
- package/dist/chunks/{velin-code-block-CIAURDRJ.js → velin-code-block-ZGWG7JI5.js} +1 -1
- package/dist/chunks/{velin-combobox-NXS4QB4R.js → velin-combobox-56V2ZWT5.js} +1 -1
- package/dist/chunks/{velin-command-ONKO2A3J.js → velin-command-2HO2EKR6.js} +29 -2
- package/dist/chunks/{velin-command-TMLSRGIU.js → velin-command-ZJSLPK7B.js} +30 -3
- package/dist/chunks/{velin-copy-NYDBOKXT.js → velin-copy-XDQSV2XU.js} +1 -1
- package/dist/chunks/{velin-countdown-4ZVDGK4R.js → velin-countdown-V4Z5MA63.js} +1 -1
- package/dist/chunks/velin-data-table-UVR42UUM.js +372 -0
- package/dist/chunks/{velin-dialog-GTTZI564.js → velin-dialog-3YK2RPRV.js} +9 -2
- package/dist/chunks/{velin-dialog-ELFOZIXZ.js → velin-dialog-S24KAP4S.js} +3 -1
- package/dist/chunks/{velin-drawer-BE6TYN3H.js → velin-drawer-5PNU624J.js} +2 -4
- package/dist/chunks/{velin-drawer-DLL2GLT6.js → velin-drawer-CCM6S25D.js} +3 -5
- package/dist/chunks/{velin-email-RBX6ZR4S.js → velin-email-TNFONXPW.js} +1 -1
- package/dist/chunks/velin-file-dropzone-QRGF2JNA.js +154 -0
- package/dist/chunks/velin-file-dropzone-XIZMJ3NB.js +154 -0
- package/dist/chunks/{velin-icon-7M76DOPB.js → velin-icon-A6NCXGUK.js} +59 -17
- package/dist/chunks/{velin-icon-ZTSKUOVN.js → velin-icon-EC4B5XCM.js} +18 -5
- package/dist/chunks/{velin-lightbox-6E7CAATP.js → velin-lightbox-FFK4TUUP.js} +7 -6
- package/dist/chunks/{velin-lightbox-NXA3U2FM.js → velin-lightbox-P725FLTY.js} +5 -4
- package/dist/chunks/{velin-menubar-J66JXRWW.js → velin-menubar-6I2LM5HL.js} +1 -1
- package/dist/chunks/{velin-modal-5HYNNNUI.js → velin-modal-ICTMGRSU.js} +7 -8
- package/dist/chunks/{velin-modal-AEOTZ67O.js → velin-modal-JBNODH7D.js} +2 -4
- package/dist/chunks/{velin-popover-T72HK3DF.js → velin-popover-WZG2GHBL.js} +25 -4
- package/dist/chunks/{velin-rating-N4DI2XNL.js → velin-rating-QBBYRRBU.js} +1 -1
- package/dist/chunks/{velin-search-7B4KJ6TX.js → velin-search-B3L6J2RP.js} +2 -2
- package/dist/chunks/{velin-search-2XRQFBCS.js → velin-search-L3UG6NDQ.js} +5 -4
- package/dist/chunks/{velin-secure-field-6PV7RZDJ.js → velin-secure-field-DGYMP7OK.js} +1 -1
- package/dist/chunks/{velin-segmented-control-GYD5BIXQ.js → velin-segmented-control-P74GJPAR.js} +1 -1
- package/dist/chunks/{velin-sheet-R2Y67X6H.js → velin-sheet-M5GZZD7G.js} +2 -4
- package/dist/chunks/{velin-sheet-OUK6572T.js → velin-sheet-X7RXIWKV.js} +3 -5
- package/dist/chunks/{velin-stepper-X54WGHDG.js → velin-stepper-4YQJUHPC.js} +12 -5
- package/dist/chunks/{velin-toast-OMMOA2DK.js → velin-toast-UG5LWTG2.js} +5 -1
- package/dist/chunks/{velin-tooltip-BDHGRTQB.js → velin-tooltip-ZDH5SDLU.js} +1 -1
- package/dist/llms.txt +29 -7
- package/dist/search-index.json +156 -10
- package/dist/velin-agent.json +3973 -28
- package/dist/velinstyle-components.iife.js +1211 -284
- package/dist/velinstyle-components.js +1213 -284
- package/dist/velinstyle-components.min.js +266 -118
- package/dist/velinstyle.css +252 -67
- package/dist/velinstyle.d.ts +2 -0
- package/dist/velinstyle.min.css +1 -1
- package/package.json +20 -6
- package/packages/skill-engine/README.md +24 -0
- package/packages/skill-engine/package.json +7 -0
- package/packages/skill-engine/src/catalog.js +29 -0
- package/packages/skill-engine/src/index.js +5 -0
- package/packages/skill-engine/src/install.js +69 -0
- package/packages/skill-engine/src/registry.js +27 -0
- package/packages/skill-engine/src/resolve.js +68 -0
- package/packages/skill-engine/src/validate.js +40 -0
- package/packages/velinstyle-skills/README.md +6 -0
- package/packages/velinstyle-skills/adapter.json +8 -0
- package/packages/velinstyle-skills/bundles/landing-starter.bundle.yaml +12 -0
- package/packages/velinstyle-skills/bundles/review-suite.bundle.yaml +11 -0
- package/packages/velinstyle-skills/catalog.json +1004 -0
- package/packages/velinstyle-skills/graphs/component-ship.graph.yaml +14 -0
- package/packages/velinstyle-skills/graphs/landingpage.graph.yaml +21 -0
- package/packages/velinstyle-skills/graphs/release-gate.graph.yaml +15 -0
- package/packages/velinstyle-skills/index.js +22 -0
- package/packages/velinstyle-skills/package.json +7 -0
- package/packages/velinstyle-skills/packs/accessibility.pack.yaml +9 -0
- package/packages/velinstyle-skills/packs/design.pack.yaml +10 -0
- package/packages/velinstyle-skills/packs/documentation.pack.yaml +8 -0
- package/packages/velinstyle-skills/packs/enterprise.pack.yaml +10 -0
- package/packages/velinstyle-skills/packs/frontend.pack.yaml +10 -0
- package/packages/velinstyle-skills/packs/review.pack.yaml +9 -0
- package/packages/velinstyle-skills/projects/admin-panel.project.yaml +12 -0
- package/packages/velinstyle-skills/projects/blog.project.yaml +11 -0
- package/packages/velinstyle-skills/projects/documentation-portal.project.yaml +13 -0
- package/packages/velinstyle-skills/projects/ecommerce-shop.project.yaml +12 -0
- package/packages/velinstyle-skills/projects/landing-page.project.yaml +12 -0
- package/packages/velinstyle-skills/projects/laravel-dashboard.project.yaml +12 -0
- package/packages/velinstyle-skills/projects/marketing-website.project.yaml +14 -0
- package/packages/velinstyle-skills/projects/portfolio.project.yaml +12 -0
- package/packages/velinstyle-skills/registry.json +142 -0
- package/packages/velinstyle-skills/scripts/generate-assets.mjs +163 -0
- package/packages/velinstyle-skills/skills/velin-a11y-focus-keyboard/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-a11y-page-checklist/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-a11y-scan-fix/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-ai-agent-briefing/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-ai-plan-scaffold-review/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-ai-skill-authoring/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-components-accessibility-map/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-components-api-contract/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-components-recipe/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-components-select-compose/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-design-hero-compose/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-design-section-rhythm/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-design-surface-roles/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-dev-component-wire/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-dev-page-scaffold/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-dev-plan-first/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-docs-component-guide/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-docs-generate-api/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-dx-doctor-setup/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-dx-project-init/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-migration-legacy-wc/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-migration-prefix-classes/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-motion-reduced-safe/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-motion-reveal-feedback/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-perf-audit-fix/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-perf-runtime-tree-shake/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-release-changelog-sync/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-release-meta-rebuild/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-review-conversion-hero/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-review-page-gate/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-review-seo-meta/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-security-sanitize-html/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-security-scan-pii/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-testing-a11y-suite/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-testing-visual-smoke/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-themes-apply-token/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-themes-contrast-check/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-utilities-layout-apply/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-utilities-prefix-fix/SKILL.md +57 -0
- package/packages/velinstyle-skills/skills/velin-utilities-token-map/SKILL.md +57 -0
- package/packages/velinstyle-skills/templates/admin-panel.template.yaml +12 -0
- package/packages/velinstyle-skills/templates/blog.template.yaml +12 -0
- package/packages/velinstyle-skills/templates/documentation-portal.template.yaml +12 -0
- package/packages/velinstyle-skills/templates/ecommerce-shop.template.yaml +13 -0
- package/packages/velinstyle-skills/templates/landing-page.template.yaml +12 -0
- package/packages/velinstyle-skills/templates/laravel-dashboard.template.yaml +11 -0
- package/packages/velinstyle-skills/templates/marketing-website.template.yaml +13 -0
- package/packages/velinstyle-skills/templates/portfolio.template.yaml +12 -0
- package/schemas/component-knowledge.schema.json +33 -0
- package/schemas/design-constraint.schema.json +15 -0
- package/schemas/design-intelligence.schema.json +19 -0
- package/schemas/design-rule.schema.json +19 -0
- package/schemas/page-template.schema.json +24 -0
- package/schemas/review-report.schema.json +36 -0
- package/schemas/section.schema.json +22 -0
- package/schemas/skill-bundle.schema.json +15 -0
- package/schemas/skill-graph.schema.json +25 -0
- package/schemas/skill-pack.schema.json +14 -0
- package/schemas/skill-project.schema.json +16 -0
- package/schemas/skill-record.schema.json +27 -0
- package/schemas/skill-registry.schema.json +17 -0
- package/schemas/skill-template.schema.json +17 -0
- package/schemas/token-graph.schema.json +27 -0
- package/schemas/utility.schema.json +166 -0
- package/src/components/alert.css +22 -1
- package/src/components/calendar-dropzone.css +5 -0
- package/src/layout/app-shell.css +33 -0
- package/src/tokens/shadow.css +13 -0
- package/src/utilities/border.css +2 -0
- package/src/utilities/display.css +1 -24
- package/src/utilities/responsive.css +16 -1
- package/src/utilities/spacing.css +32 -0
- package/src/velinstyle.css +2 -0
- package/dist/chunks/attributes-3BZLI7XF.js +0 -364
- package/dist/chunks/attributes-4N5JP4CG.js +0 -364
- package/dist/chunks/attributes-5Q2WXGRC.js +0 -374
- package/dist/chunks/attributes-AIR7SVLK.js +0 -364
- package/dist/chunks/attributes-BGRN5XZO.js +0 -364
- package/dist/chunks/attributes-BVSQAYLR.js +0 -364
- package/dist/chunks/attributes-CDYFUY7Y.js +0 -364
- package/dist/chunks/attributes-JMYJZBPE.js +0 -364
- package/dist/chunks/attributes-R5JY3X4O.js +0 -374
- package/dist/chunks/attributes-TNSPQTHX.js +0 -374
- package/dist/chunks/chunk-2354NEBP.js +0 -109
- package/dist/chunks/chunk-2VNA7G7S.js +0 -109
- package/dist/chunks/chunk-AQLRJSGG.js +0 -109
- package/dist/chunks/chunk-EWPSDMQT.js +0 -109
- package/dist/chunks/chunk-LA7264K4.js +0 -85
- package/dist/chunks/chunk-QTJJ3DPO.js +0 -109
- package/dist/chunks/chunk-RZQVWFHW.js +0 -109
- package/dist/chunks/chunk-U4XHMZ7D.js +0 -109
- package/dist/chunks/chunk-V5YIUA6G.js +0 -109
- package/dist/chunks/chunk-XIET2VSZ.js +0 -109
- package/dist/chunks/chunk-XYLJ2GCB.js +0 -205
- package/dist/chunks/chunk-ZPSPKUYD.js +0 -109
- package/dist/chunks/highlight-XTHRKBA3.js +0 -37
- package/dist/chunks/velin-bottom-nav-2N2TYWOF.js +0 -86
- package/dist/chunks/velin-carousel-Y5VCOABZ.js +0 -213
- package/dist/chunks/velin-code-block-ASUBTAQV.js +0 -119
- package/dist/chunks/velin-code-block-TSUKPY4C.js +0 -123
- package/dist/chunks/velin-code-block-Y6CM726Q.js +0 -119
- package/dist/chunks/velin-combobox-2KDTCQ7N.js +0 -155
- package/dist/chunks/velin-command-M7RNHUPR.js +0 -136
- package/dist/chunks/velin-copy-T5KDTDXP.js +0 -81
- package/dist/chunks/velin-countdown-5XSTN3BH.js +0 -101
- package/dist/chunks/velin-counter-ISCTEAHI.js +0 -118
- package/dist/chunks/velin-dialog-D2GUHSCD.js +0 -144
- package/dist/chunks/velin-dialog-IJLFDXAJ.js +0 -144
- package/dist/chunks/velin-dialog-TNS3WXMB.js +0 -144
- package/dist/chunks/velin-drawer-MJS6WCF7.js +0 -130
- package/dist/chunks/velin-email-N5B5ZYTE.js +0 -90
- package/dist/chunks/velin-icon-KZO3IEHG.js +0 -164
- package/dist/chunks/velin-lightbox-I75U6JF4.js +0 -140
- package/dist/chunks/velin-lightbox-QOTB4PRL.js +0 -140
- package/dist/chunks/velin-lightbox-UCD6N7HF.js +0 -140
- package/dist/chunks/velin-live-dot-XHUZCIDZ.js +0 -67
- package/dist/chunks/velin-menubar-SFEXJE56.js +0 -86
- package/dist/chunks/velin-modal-2HOBXE6F.js +0 -176
- package/dist/chunks/velin-modal-GLI2XZZB.js +0 -176
- package/dist/chunks/velin-popover-EXINRIGJ.js +0 -145
- package/dist/chunks/velin-popover-OXX7MRZ6.js +0 -145
- package/dist/chunks/velin-popover-YKCCROJG.js +0 -145
- package/dist/chunks/velin-rating-XRQJV4LO.js +0 -91
- package/dist/chunks/velin-scroll-top-F2FCZNYD.js +0 -58
- package/dist/chunks/velin-search-4YHJWYSS.js +0 -556
- package/dist/chunks/velin-search-LWHY23Q5.js +0 -474
- package/dist/chunks/velin-secure-field-H7FSBUJW.js +0 -95
- package/dist/chunks/velin-segmented-control-PQX6LKOJ.js +0 -109
- package/dist/chunks/velin-sheet-3OGI4HD7.js +0 -119
- package/dist/chunks/velin-sparkline-GVEANJVW.js +0 -184
- package/dist/chunks/velin-sparkline-KDA3GQAN.js +0 -162
- package/dist/chunks/velin-stepper-2ZIHLKGM.js +0 -141
- package/dist/chunks/velin-stepper-FYEUEWE6.js +0 -141
- package/dist/chunks/velin-stepper-wc-QU3KRVQR.js +0 -133
- package/dist/chunks/velin-theme-toggle-BNNS7WLV.js +0 -285
- package/dist/chunks/velin-theme-toggle-NO7V4TWI.js +0 -285
- package/dist/chunks/velin-theme-toggle-QELCJM2Q.js +0 -291
- package/dist/chunks/velin-toast-RCZ4CSUC.js +0 -109
- package/dist/chunks/velin-toast-WEUBTJG6.js +0 -109
- package/dist/chunks/velin-tooltip-664IOHZA.js +0 -112
- package/dist/chunks/velin-tooltip-wc-LXDVT6DE.js +0 -103
- package/dist/chunks/worker-client-R6DBYPFT.js +0 -46
package/cli/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync, rmSync, statSync } from 'fs';
|
|
4
4
|
import { join, resolve, basename, dirname } from 'path';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
7
7
|
import { listProviders, getProviderUrl, PROVIDERS } from './icon-providers.js';
|
|
8
8
|
|
|
9
9
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
@@ -33,7 +33,7 @@ const LAYER_FILES = {
|
|
|
33
33
|
security: ['a11y/security.css'],
|
|
34
34
|
layout: [
|
|
35
35
|
'layout/breakpoints.css', 'layout/container.css', 'layout/grid.css',
|
|
36
|
-
'layout/flex.css', 'layout/patterns.css',
|
|
36
|
+
'layout/flex.css', 'layout/patterns.css', 'layout/app-shell.css',
|
|
37
37
|
],
|
|
38
38
|
components: [
|
|
39
39
|
'components/button.css', 'components/card.css', 'components/input.css',
|
|
@@ -44,6 +44,7 @@ const LAYER_FILES = {
|
|
|
44
44
|
'components/switch.css', 'components/divider.css', 'components/chip.css',
|
|
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
|
+
'components/calendar-dropzone.css',
|
|
47
48
|
],
|
|
48
49
|
utilities: [
|
|
49
50
|
'utilities/color.css', 'utilities/spacing.css', 'utilities/display.css',
|
|
@@ -93,10 +94,18 @@ function help() {
|
|
|
93
94
|
velinstyle themes List available themes
|
|
94
95
|
velinstyle add <name> Add a single component CSS
|
|
95
96
|
velinstyle icons <subcommand> Manage icon providers
|
|
96
|
-
velinstyle scan [path]
|
|
97
|
+
velinstyle scan [path|file] Security & accessibility scanner (dir or .html/.css/.js)
|
|
97
98
|
velinstyle prefix [path] Add missing velin- prefix (dry-run; use --write)
|
|
98
99
|
velinstyle blueprint [name] Print HTML blueprint (run: velinstyle blueprint list)
|
|
99
|
-
velinstyle
|
|
100
|
+
velinstyle blueprint <name> --strict Fail if emitted classes ∉ CSS
|
|
101
|
+
velinstyle create <kind> [dir] Scaffold: landing|dashboard|docs|auth
|
|
102
|
+
velinstyle serve [dir] Static preview server (default port 4173)
|
|
103
|
+
velinstyle doctor Check dist, icons, config, Windows ESM paths
|
|
104
|
+
velinstyle check [path] doctor + blueprint --strict + scan + review
|
|
105
|
+
velinstyle scaffold "<prompt>" Plan-first page HTML or recipe fragment
|
|
106
|
+
velinstyle plan "<prompt>" Emit page plan JSON (no HTML)
|
|
107
|
+
velinstyle review [file|html] Design / a11y / SEO / conversion review gate
|
|
108
|
+
velinstyle wc api <tag> Human-readable Web Component API from source
|
|
100
109
|
velinstyle layout <sub> Responsive layout audit and fixes
|
|
101
110
|
velinstyle perf <sub> Performance audit (images, scripts) with --fix
|
|
102
111
|
velinstyle tokens build Generate CSS variables from tokens.json
|
|
@@ -104,6 +113,8 @@ function help() {
|
|
|
104
113
|
velinstyle docs generate Auto-generate Markdown API reference
|
|
105
114
|
velinstyle meta Build agent context (velin-agent.json, llms.txt)
|
|
106
115
|
velinstyle search index Build JSON search index for VelinSearch
|
|
116
|
+
velinstyle skills <subcommand> Registry-first AI skills commands
|
|
117
|
+
velinstyle workflow <id> Resolve workflow graph / project workflow
|
|
107
118
|
|
|
108
119
|
${C.bold('Icons subcommands:')}
|
|
109
120
|
icons list Show available icon providers
|
|
@@ -117,23 +128,37 @@ function help() {
|
|
|
117
128
|
velinstyle icons build
|
|
118
129
|
|
|
119
130
|
${C.bold('Blueprint:')}
|
|
120
|
-
velinstyle blueprint list
|
|
121
|
-
velinstyle blueprint <name> [--output, -o <file>]
|
|
122
|
-
|
|
123
|
-
${C.bold('
|
|
124
|
-
velinstyle
|
|
125
|
-
velinstyle
|
|
131
|
+
velinstyle blueprint list [--strict] Print ids (strict validates all)
|
|
132
|
+
velinstyle blueprint <name> [--output, -o <file>] [--strict]
|
|
133
|
+
|
|
134
|
+
${C.bold('Create / serve / doctor / check:')}
|
|
135
|
+
velinstyle create landing|dashboard|docs|auth [dir] [--theme earth] [--no-copy]
|
|
136
|
+
velinstyle serve [dir] [--port 4173]
|
|
137
|
+
velinstyle doctor
|
|
138
|
+
velinstyle check [path] [--json|--sarif] [--profile marketing|app|docs|fragment|ecommerce]
|
|
139
|
+
Alias: validate → check · documentation → docs generate help
|
|
140
|
+
|
|
141
|
+
${C.bold('Web Components:')}
|
|
142
|
+
velinstyle wc api <tag> e.g. velinstyle wc api velin-toast
|
|
143
|
+
|
|
144
|
+
${C.bold('Scaffold (1.2.0):')}
|
|
145
|
+
velinstyle scaffold "<prompt>" Plan → render → review for pages; recipes for fragments
|
|
146
|
+
velinstyle scaffold list-intents Show recipe intent keywords
|
|
126
147
|
velinstyle scaffold "<prompt>" -o out.html [--json]
|
|
127
148
|
|
|
149
|
+
${C.bold('Plan / Review (1.2.0):')}
|
|
150
|
+
velinstyle plan "<prompt>" [--json] [-o plan.json]
|
|
151
|
+
velinstyle review <file.html> [--json] [--prompt "..."]
|
|
152
|
+
|
|
128
153
|
${C.bold('Layout (0.8.0):')}
|
|
129
154
|
velinstyle layout audit [path] Report flex/grid/responsive issues
|
|
130
155
|
velinstyle layout suggest [path] Audit with fix suggestions
|
|
131
156
|
velinstyle layout fix [path] Apply safe fixes (--dry-run default, --write)
|
|
132
157
|
|
|
133
158
|
${C.bold('Performance (0.9.0):')}
|
|
134
|
-
velinstyle perf audit [path]
|
|
135
|
-
velinstyle perf suggest [path]
|
|
136
|
-
velinstyle perf fix [path]
|
|
159
|
+
velinstyle perf audit [path|file] Report CLS, lazy-load, script defer issues
|
|
160
|
+
velinstyle perf suggest [path|file] Same as audit with fix hints
|
|
161
|
+
velinstyle perf fix [path|file] Apply safe fixes (--write)
|
|
137
162
|
|
|
138
163
|
${C.bold('Tokens:')}
|
|
139
164
|
velinstyle tokens build [--input <path>] [--output, -o <file>]
|
|
@@ -142,17 +167,28 @@ function help() {
|
|
|
142
167
|
${C.bold('Docs (0.9.0):')}
|
|
143
168
|
velinstyle docs generate [--scope all|components|tokens|utilities|cli|rules|a11y|meta] [--out docs/generated]
|
|
144
169
|
velinstyle meta [--out dist/velin-agent.json] [--llms-out dist/llms.txt] [--base-url URL]
|
|
145
|
-
velinstyle meta page <file.html> [--write]
|
|
170
|
+
velinstyle meta page <file.html> [--write] Merge curated meta (goals/intent) on --write
|
|
146
171
|
|
|
147
172
|
${C.bold('Search:')}
|
|
148
173
|
velinstyle search index [--out dist/search-index.json] [--extra-html dir1,dir2]
|
|
149
174
|
|
|
175
|
+
${C.bold('Skills:')}
|
|
176
|
+
velinstyle skills list [--capability review] [--status beta] [--json]
|
|
177
|
+
velinstyle skills show <skill-id> [--human]
|
|
178
|
+
velinstyle skills install <skill-id|pack|bundle:id|project:id> [--target .cursor/skills]
|
|
179
|
+
velinstyle skills run <skill-id> [--json]
|
|
180
|
+
velinstyle skills validate
|
|
181
|
+
velinstyle skills packs|bundles|templates|projects|graphs
|
|
182
|
+
|
|
183
|
+
${C.bold('Workflow:')}
|
|
184
|
+
velinstyle workflow <graph-id|project:id> [--json]
|
|
185
|
+
|
|
150
186
|
${C.bold('Scan options:')}
|
|
151
187
|
--fix Auto-fix safe issues (writes files)
|
|
152
188
|
--fix-dry-run Show files that would be auto-fixed; no write
|
|
153
189
|
--fix-lang <code> Default lang for a11y/html-lang fix (default: de)
|
|
154
190
|
--severity <level> Minimum severity: error, warning, info
|
|
155
|
-
--only <category> Filter: security, pii, a11y, css, perf
|
|
191
|
+
--only <category> Filter: security, pii, a11y, css, wc, perf
|
|
156
192
|
|
|
157
193
|
${C.bold('Prefix options (velinstyle prefix):')}
|
|
158
194
|
--write Write files (default is dry-run)
|
|
@@ -166,6 +202,7 @@ function help() {
|
|
|
166
202
|
${C.bold('Build options:')}
|
|
167
203
|
--output, -o <path> Output file path (default: ./velinstyle-custom.css)
|
|
168
204
|
--minify Minify output
|
|
205
|
+
--preset lite Marketing subset layers (tokens+reset+base+layout+components+utilities)
|
|
169
206
|
|
|
170
207
|
${C.bold('General:')}
|
|
171
208
|
--help, -h Show this help
|
|
@@ -178,36 +215,86 @@ function init() {
|
|
|
178
215
|
const configPath = resolve('velinstyle.config.js');
|
|
179
216
|
if (existsSync(configPath)) {
|
|
180
217
|
console.log('velinstyle.config.js already exists.');
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const config = `// VelinStyle Configuration
|
|
218
|
+
} else {
|
|
219
|
+
const config = `// VelinStyle Configuration
|
|
185
220
|
export default {
|
|
221
|
+
// Marketing lite: layers: ['tokens','reset','base','layout','components','utilities'] + theme
|
|
222
|
+
// See docs/guides/marketing-lite-css.html
|
|
186
223
|
layers: [
|
|
187
|
-
'tokens',
|
|
188
|
-
'reset',
|
|
189
|
-
'base',
|
|
190
|
-
'a11y',
|
|
191
|
-
'layout',
|
|
192
|
-
'components',
|
|
193
|
-
'utilities',
|
|
194
|
-
'helpers',
|
|
224
|
+
'tokens',
|
|
225
|
+
'reset',
|
|
226
|
+
'base',
|
|
227
|
+
'a11y',
|
|
228
|
+
'layout',
|
|
229
|
+
'components',
|
|
230
|
+
'utilities',
|
|
231
|
+
'helpers',
|
|
195
232
|
],
|
|
196
|
-
theme: null, // e.g. '
|
|
233
|
+
theme: null, // e.g. 'earth', 'nordic', 'ocean'
|
|
197
234
|
output: './velinstyle-custom.css',
|
|
198
235
|
minify: true,
|
|
199
236
|
scan: {
|
|
200
|
-
enabled: false,
|
|
237
|
+
enabled: false,
|
|
201
238
|
severity: 'warning',
|
|
202
239
|
fix: false,
|
|
203
240
|
ignore: ['node_modules', 'dist', '.git'],
|
|
204
241
|
},
|
|
205
242
|
};
|
|
206
243
|
`;
|
|
244
|
+
writeFileSync(configPath, config);
|
|
245
|
+
console.log(C.green('Created velinstyle.config.js'));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const vendorDir = resolve('vendor', 'velinstyle');
|
|
249
|
+
const distCss = join(PKG_ROOT, 'dist', 'velinstyle.min.css');
|
|
250
|
+
if (existsSync(distCss)) {
|
|
251
|
+
mkdirSync(vendorDir, { recursive: true });
|
|
252
|
+
for (const f of ['velinstyle.min.css', 'velinstyle-components.min.js', 'velin-icons.svg']) {
|
|
253
|
+
const src = join(PKG_ROOT, 'dist', f);
|
|
254
|
+
if (existsSync(src)) writeFileSync(join(vendorDir, f), readFileSync(src));
|
|
255
|
+
}
|
|
256
|
+
const themesSrc = join(PKG_ROOT, 'dist', 'themes');
|
|
257
|
+
if (existsSync(themesSrc)) {
|
|
258
|
+
mkdirSync(join(vendorDir, 'themes'), { recursive: true });
|
|
259
|
+
for (const name of readdirSync(themesSrc)) {
|
|
260
|
+
const src = join(themesSrc, name);
|
|
261
|
+
if (statSync(src).isFile()) writeFileSync(join(vendorDir, 'themes', name), readFileSync(src));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
console.log(C.green(`Copied dist assets → ${vendorDir}`));
|
|
265
|
+
} else {
|
|
266
|
+
console.log(C.yellow('Framework dist/ not found — skip vendor copy. Build the framework or copy dist manually into vendor/velinstyle.'));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const starter = resolve('index.velin-starter.html');
|
|
270
|
+
if (!existsSync(starter) && !existsSync(resolve('index.html'))) {
|
|
271
|
+
writeFileSync(
|
|
272
|
+
starter,
|
|
273
|
+
`<!DOCTYPE html>
|
|
274
|
+
<html lang="en" data-velin-reveal-auto>
|
|
275
|
+
<head>
|
|
276
|
+
<meta charset="UTF-8">
|
|
277
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
278
|
+
<meta name="velin-icon-sprite" content="vendor/velinstyle/velin-icons.svg">
|
|
279
|
+
<title>VelinStyle starter</title>
|
|
280
|
+
<link rel="stylesheet" href="vendor/velinstyle/velinstyle.min.css">
|
|
281
|
+
</head>
|
|
282
|
+
<body>
|
|
283
|
+
<a class="velin-skip-link" href="#main">Skip to main</a>
|
|
284
|
+
<main id="main" class="velin-container velin-py-8">
|
|
285
|
+
<h1 class="velin-text-3xl velin-font-bold">VelinStyle starter</h1>
|
|
286
|
+
<p class="velin-text-muted">Run <code>velinstyle serve</code> or <code>velinstyle create landing</code>.</p>
|
|
287
|
+
</main>
|
|
288
|
+
<script type="module" src="vendor/velinstyle/velinstyle-components.min.js"></script>
|
|
289
|
+
</body>
|
|
290
|
+
</html>
|
|
291
|
+
`,
|
|
292
|
+
'utf-8',
|
|
293
|
+
);
|
|
294
|
+
console.log(C.green('Created index.velin-starter.html'));
|
|
295
|
+
}
|
|
207
296
|
|
|
208
|
-
|
|
209
|
-
console.log(C.green('Created velinstyle.config.js'));
|
|
210
|
-
console.log('Edit the layers array, then run: velinstyle build');
|
|
297
|
+
console.log('Next: velinstyle build · velinstyle serve · velinstyle doctor');
|
|
211
298
|
}
|
|
212
299
|
|
|
213
300
|
// ── Build ────────────────────────────────────────────────────────────────────
|
|
@@ -217,12 +304,18 @@ async function build() {
|
|
|
217
304
|
let config;
|
|
218
305
|
|
|
219
306
|
if (existsSync(configPath)) {
|
|
220
|
-
config = (await import(configPath)).default;
|
|
307
|
+
config = (await import(pathToFileURL(configPath).href)).default;
|
|
221
308
|
} else {
|
|
222
309
|
config = { layers: LAYERS, theme: null, output: './velinstyle-custom.css', minify: true };
|
|
223
310
|
}
|
|
224
311
|
|
|
225
|
-
const
|
|
312
|
+
const LITE_LAYERS = ['tokens', 'reset', 'base', 'layout', 'components', 'utilities'];
|
|
313
|
+
const preset = getArg('--preset') || config.preset;
|
|
314
|
+
if (preset === 'lite') {
|
|
315
|
+
config = { ...config, layers: LITE_LAYERS };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const output = getArg('--output', '-o') || getArg('--out') || config.output || './velinstyle-custom.css';
|
|
226
319
|
const minify = hasFlag('--minify') || config.minify;
|
|
227
320
|
const selectedLayers = config.layers || LAYERS;
|
|
228
321
|
|
|
@@ -254,19 +347,42 @@ async function build() {
|
|
|
254
347
|
const tmpPath = resolve('.velinstyle-tmp.css');
|
|
255
348
|
writeFileSync(tmpPath, css);
|
|
256
349
|
|
|
350
|
+
const outAbs = resolve(output);
|
|
351
|
+
let bundled = false;
|
|
257
352
|
try {
|
|
353
|
+
const binName = process.platform === 'win32' ? 'lightningcss.cmd' : 'lightningcss';
|
|
354
|
+
const localBin = join(PKG_ROOT, 'node_modules', '.bin', binName);
|
|
355
|
+
const cli = existsSync(localBin) ? `"${localBin}"` : 'npx lightningcss';
|
|
258
356
|
const minifyFlag = minify ? '--minify' : '';
|
|
259
|
-
execSync(
|
|
357
|
+
execSync(`${cli} --bundle ${minifyFlag} "${tmpPath}" -o "${outAbs}"`, {
|
|
260
358
|
stdio: 'inherit',
|
|
359
|
+
cwd: PKG_ROOT,
|
|
360
|
+
shell: true,
|
|
261
361
|
});
|
|
362
|
+
bundled = true;
|
|
262
363
|
console.log(C.green(`Built: ${output}`) + ` (layers: ${selectedLayers.join(', ')}${config.theme ? ', theme: ' + config.theme : ''})`);
|
|
263
364
|
} catch {
|
|
264
|
-
writeFileSync(
|
|
365
|
+
writeFileSync(outAbs, css);
|
|
265
366
|
console.log(C.yellow(`Built (unbundled): ${output}`));
|
|
367
|
+
console.log(C.yellow(' Install lightningcss-cli in the VelinStyle package (or run build from the framework repo) for minified output.'));
|
|
266
368
|
} finally {
|
|
267
369
|
try { unlinkSync(tmpPath); } catch { /* ignore */ }
|
|
268
370
|
}
|
|
269
371
|
|
|
372
|
+
if (preset === 'lite' && existsSync(outAbs)) {
|
|
373
|
+
const liteBytes = statSync(outAbs).size;
|
|
374
|
+
const fullMin = join(PKG_ROOT, 'dist', 'velinstyle.min.css');
|
|
375
|
+
if (existsSync(fullMin)) {
|
|
376
|
+
const fullBytes = statSync(fullMin).size;
|
|
377
|
+
const liteKb = (liteBytes / 1024).toFixed(1);
|
|
378
|
+
const fullKb = (fullBytes / 1024).toFixed(1);
|
|
379
|
+
console.log(` Size: lite ${liteKb} KB vs dist/velinstyle.min.css ${fullKb} KB`);
|
|
380
|
+
if (!bundled || liteBytes >= fullBytes) {
|
|
381
|
+
console.log(C.yellow(` Warning: lite output is not smaller than the full min CSS${bundled ? '' : ' (unbundled)'}.`));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
270
386
|
if (config.scan?.enabled) {
|
|
271
387
|
console.log(C.dim('\nRunning post-build scan...'));
|
|
272
388
|
const { scan } = await import('./scanner.js');
|
|
@@ -458,18 +574,41 @@ function iconsBuildCmd() {
|
|
|
458
574
|
|
|
459
575
|
async function blueprintCmd() {
|
|
460
576
|
const sub = args[1];
|
|
461
|
-
const
|
|
577
|
+
const strict = hasFlag('--strict');
|
|
578
|
+
const { listBlueprints, emitBlueprint, validateAllBlueprints } = await import('./blueprint.js');
|
|
579
|
+
if (sub === '--help' || sub === '-h') {
|
|
580
|
+
console.log(`Usage: velinstyle blueprint [list|<name>] [--output|-o <file>] [--strict]
|
|
581
|
+
|
|
582
|
+
list List blueprint ids
|
|
583
|
+
list --strict Validate all blueprints against CSS
|
|
584
|
+
<name> Emit HTML (stdout or -o file)
|
|
585
|
+
<name> --strict Fail if classes missing from CSS
|
|
586
|
+
`);
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
462
589
|
if (!sub || sub === 'list') {
|
|
590
|
+
if (strict) {
|
|
591
|
+
const results = validateAllBlueprints();
|
|
592
|
+
const bad = results.filter((r) => !r.ok);
|
|
593
|
+
if (bad.length) {
|
|
594
|
+
for (const r of bad) {
|
|
595
|
+
console.log(C.red(`${r.id}: ${r.missing?.join(', ') || r.error}`));
|
|
596
|
+
}
|
|
597
|
+
process.exit(1);
|
|
598
|
+
}
|
|
599
|
+
console.log(C.green(`All ${results.length} blueprints pass --strict`));
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
463
602
|
console.log(`\n ${C.bold('Available blueprints:')}\n`);
|
|
464
603
|
listBlueprints().forEach((b) => console.log(` - ${b}`));
|
|
465
|
-
console.log(`\n ${C.dim('Example: velinstyle blueprint modal -o snippet.html')}\n`);
|
|
604
|
+
console.log(`\n ${C.dim('Example: velinstyle blueprint modal -o snippet.html --strict')}\n`);
|
|
466
605
|
return;
|
|
467
606
|
}
|
|
468
607
|
const out = getArg('--output', '-o');
|
|
469
|
-
const r = emitBlueprint(sub, { output: out || null });
|
|
608
|
+
const r = emitBlueprint(sub, { output: out || null, strict });
|
|
470
609
|
if (!r.ok) {
|
|
471
610
|
console.log(C.red(r.error));
|
|
472
|
-
|
|
611
|
+
process.exit(1);
|
|
473
612
|
}
|
|
474
613
|
if (r.text) {
|
|
475
614
|
console.log(r.text);
|
|
@@ -478,6 +617,58 @@ async function blueprintCmd() {
|
|
|
478
617
|
}
|
|
479
618
|
}
|
|
480
619
|
|
|
620
|
+
async function serveCmd() {
|
|
621
|
+
const raw = args[1] && !args[1].startsWith('-') ? args[1] : '.';
|
|
622
|
+
const port = Number(getArg('--port')) || 4173;
|
|
623
|
+
const { serveStatic } = await import('./serve.js');
|
|
624
|
+
const result = await serveStatic({ dir: resolve(raw), port });
|
|
625
|
+
if (!result.ok) {
|
|
626
|
+
console.log(C.red(result.error));
|
|
627
|
+
process.exit(1);
|
|
628
|
+
}
|
|
629
|
+
console.log(C.green(`Serving ${result.dir}`));
|
|
630
|
+
console.log(` ${result.url}`);
|
|
631
|
+
console.log(C.dim('Press Ctrl+C to stop'));
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
async function doctorCmd() {
|
|
635
|
+
const { runDoctor, formatDoctorReport } = await import('./doctor.js');
|
|
636
|
+
const raw = args[1] && !args[1].startsWith('-') ? resolve(args[1]) : process.cwd();
|
|
637
|
+
let cwd = raw;
|
|
638
|
+
try {
|
|
639
|
+
if (existsSync(raw) && statSync(raw).isFile()) cwd = dirname(raw);
|
|
640
|
+
} catch { /* use raw */ }
|
|
641
|
+
const report = await runDoctor({ cwd, pkgRoot: PKG_ROOT });
|
|
642
|
+
console.log(formatDoctorReport(report));
|
|
643
|
+
process.exit(report.ok ? 0 : 1);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
async function createCmd() {
|
|
647
|
+
const kind = args[1];
|
|
648
|
+
if (!kind || kind === '--help' || kind === '-h') {
|
|
649
|
+
console.log(`Usage: velinstyle create <landing|dashboard|docs|auth> [dir] [--theme earth] [--no-copy]`);
|
|
650
|
+
process.exit(kind ? 0 : 1);
|
|
651
|
+
}
|
|
652
|
+
const { CREATE_KINDS, createProject } = await import('./create.js');
|
|
653
|
+
if (!CREATE_KINDS.includes(kind)) {
|
|
654
|
+
console.log(C.red(`Unknown kind "${kind}". Use: ${CREATE_KINDS.join('|')}`));
|
|
655
|
+
process.exit(1);
|
|
656
|
+
}
|
|
657
|
+
const dir = args[2] && !args[2].startsWith('-') ? args[2] : kind;
|
|
658
|
+
const theme = getArg('--theme') || undefined;
|
|
659
|
+
const copyAssets = !hasFlag('--no-copy');
|
|
660
|
+
const r = createProject({ kind, dir: resolve(dir), pkgRoot: PKG_ROOT, theme, copyAssets });
|
|
661
|
+
if (!r.ok) {
|
|
662
|
+
console.log(C.red(r.error));
|
|
663
|
+
process.exit(1);
|
|
664
|
+
}
|
|
665
|
+
console.log(C.green(`Created ${kind} at ${r.dir}`));
|
|
666
|
+
console.log(C.dim(` index: ${r.indexPath}`));
|
|
667
|
+
if (r.vendorRel) console.log(C.dim(` vendor: ${r.vendorRel}/`));
|
|
668
|
+
if (r.vendorCopied?.length) console.log(C.dim(` copied: ${r.vendorCopied.join(', ')}`));
|
|
669
|
+
console.log(C.dim(` Next: velinstyle serve ${dir} · velinstyle check ${dir}`));
|
|
670
|
+
}
|
|
671
|
+
|
|
481
672
|
async function tokensBuildCmd() {
|
|
482
673
|
const inputPath = resolve(getArg('--input') || 'tokens.json');
|
|
483
674
|
const outPath = getArg('--output', '-o');
|
|
@@ -622,7 +813,10 @@ async function scaffoldCmd() {
|
|
|
622
813
|
console.log(JSON.stringify(r, null, 2));
|
|
623
814
|
} else if (out) {
|
|
624
815
|
writeFileSync(resolve(out), r.html, 'utf-8');
|
|
625
|
-
console.log(C.green(`Wrote ${resolve(out)} (intent: ${r.intent}, ${r.confidence})`));
|
|
816
|
+
console.log(C.green(`Wrote ${resolve(out)} (intent: ${r.intent}, ${r.confidence}${r.mode ? `, mode: ${r.mode}` : ''})`));
|
|
817
|
+
if (r.review?.gate) {
|
|
818
|
+
console.log(C.dim(` review gate: ${r.review.gate} (promptScore ${r.review.promptScore})`));
|
|
819
|
+
}
|
|
626
820
|
if (r.responsiveHints?.length) {
|
|
627
821
|
console.log(C.yellow(` ${r.responsiveHints.length} layout hint(s) — run: velinstyle layout suggest ${out}`));
|
|
628
822
|
}
|
|
@@ -631,6 +825,74 @@ async function scaffoldCmd() {
|
|
|
631
825
|
}
|
|
632
826
|
}
|
|
633
827
|
|
|
828
|
+
async function planCmd() {
|
|
829
|
+
const promptParts = [];
|
|
830
|
+
let i = 1;
|
|
831
|
+
while (i < args.length) {
|
|
832
|
+
const a = args[i];
|
|
833
|
+
if (a.startsWith('-')) break;
|
|
834
|
+
promptParts.push(a);
|
|
835
|
+
i += 1;
|
|
836
|
+
}
|
|
837
|
+
const prompt = promptParts.join(' ').trim();
|
|
838
|
+
if (!prompt) {
|
|
839
|
+
console.log('Usage: velinstyle plan "<description>" [--json] [-o plan.json]');
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
const { analyzePrompt, buildPlan } = await import('./prompt-engine.js');
|
|
843
|
+
const analysis = analyzePrompt(prompt);
|
|
844
|
+
const plan = buildPlan(analysis, prompt);
|
|
845
|
+
const payload = { analysis, plan };
|
|
846
|
+
const out = getArg('--output', '-o');
|
|
847
|
+
if (out) {
|
|
848
|
+
writeFileSync(resolve(out), JSON.stringify(payload, null, 2), 'utf-8');
|
|
849
|
+
console.log(C.green(`Wrote plan ${resolve(out)} (page: ${plan.page?.id}, sections: ${plan.sections.length})`));
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
async function reviewCmd() {
|
|
856
|
+
const target = args[1] && !args[1].startsWith('-') ? args[1] : null;
|
|
857
|
+
if (!target) {
|
|
858
|
+
console.log('Usage: velinstyle review <file.html> [--json] [--prompt "..."] [--profile marketing|app|docs|fragment]');
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
const full = resolve(target);
|
|
862
|
+
if (!existsSync(full)) {
|
|
863
|
+
console.log(C.red(`File not found: ${full}`));
|
|
864
|
+
process.exit(1);
|
|
865
|
+
}
|
|
866
|
+
const html = readFileSync(full, 'utf-8');
|
|
867
|
+
const prompt = getArg('--prompt') || '';
|
|
868
|
+
const profile = getArg('--profile');
|
|
869
|
+
let plan;
|
|
870
|
+
if (prompt) {
|
|
871
|
+
const { analyzePrompt, buildPlan } = await import('./prompt-engine.js');
|
|
872
|
+
plan = buildPlan(analyzePrompt(prompt), prompt);
|
|
873
|
+
}
|
|
874
|
+
const { reviewHtml } = await import('./review.js');
|
|
875
|
+
const report = reviewHtml(html, { plan, prompt, profile: profile || undefined });
|
|
876
|
+
if (hasFlag('--json')) {
|
|
877
|
+
console.log(JSON.stringify(report, null, 2));
|
|
878
|
+
} else {
|
|
879
|
+
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}`));
|
|
881
|
+
if (report.issues.length) {
|
|
882
|
+
console.log(`\n ${C.bold('Issues:')}`);
|
|
883
|
+
for (const issue of report.issues) {
|
|
884
|
+
const color = issue.severity === 'error' ? C.red : C.yellow;
|
|
885
|
+
console.log(color(` [${issue.severity}] ${issue.code}: ${issue.message}`));
|
|
886
|
+
console.log(C.dim(` fix: ${issue.fix}`));
|
|
887
|
+
}
|
|
888
|
+
} else {
|
|
889
|
+
console.log(C.green('\n No issues.'));
|
|
890
|
+
}
|
|
891
|
+
console.log('');
|
|
892
|
+
}
|
|
893
|
+
process.exit(report.gate === 'fail' ? 1 : 0);
|
|
894
|
+
}
|
|
895
|
+
|
|
634
896
|
async function layoutCmd() {
|
|
635
897
|
const sub = args[1] || 'audit';
|
|
636
898
|
const rawTarget = args[2] && !args[2].startsWith('-') ? args[2] : '.';
|
|
@@ -722,6 +984,38 @@ async function searchCmd() {
|
|
|
722
984
|
console.log('Usage: velinstyle search index [--out <file>] [--extra-html dir1,dir2]');
|
|
723
985
|
}
|
|
724
986
|
|
|
987
|
+
async function skillsCmd() {
|
|
988
|
+
const { skillsCommand } = await import('./skills.js');
|
|
989
|
+
await skillsCommand(args.slice(1));
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
async function workflowCmd() {
|
|
993
|
+
const { workflowCommand } = await import('./workflow.js');
|
|
994
|
+
await workflowCommand(args.slice(1));
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
async function wcCmd() {
|
|
998
|
+
const sub = args[1];
|
|
999
|
+
if (sub === 'api' || sub === '--help' || sub === '-h' || !sub) {
|
|
1000
|
+
if (sub !== 'api') {
|
|
1001
|
+
console.log(`Usage: velinstyle wc api <tag>\nExample: velinstyle wc api velin-toast`);
|
|
1002
|
+
if (sub === '--help' || sub === '-h' || !sub) process.exit(0);
|
|
1003
|
+
}
|
|
1004
|
+
const tag = args[2];
|
|
1005
|
+
const { describeWcApi, formatWcApi } = await import('./wc-api.js');
|
|
1006
|
+
const report = describeWcApi(PKG_ROOT, tag);
|
|
1007
|
+
if (!report.ok) {
|
|
1008
|
+
console.error(report.error);
|
|
1009
|
+
process.exit(1);
|
|
1010
|
+
}
|
|
1011
|
+
if (hasFlag('--json')) console.log(JSON.stringify(report, null, 2));
|
|
1012
|
+
else console.log(formatWcApi(report));
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
console.error(`Unknown wc subcommand: ${sub}. Use: velinstyle wc api <tag>`);
|
|
1016
|
+
process.exit(1);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
725
1019
|
async function scanCmd() {
|
|
726
1020
|
const targetPath = args[1] && !args[1].startsWith('-') ? resolve(args[1]) : resolve('.');
|
|
727
1021
|
const format = getArg('--format') || 'text';
|
|
@@ -747,24 +1041,217 @@ async function scanCmd() {
|
|
|
747
1041
|
process.exit(exitCode);
|
|
748
1042
|
}
|
|
749
1043
|
|
|
1044
|
+
async function checkCmd() {
|
|
1045
|
+
const raw = args[1] && !args[1].startsWith('-') ? args[1] : '.';
|
|
1046
|
+
const target = resolve(raw);
|
|
1047
|
+
const asJson = hasFlag('--json');
|
|
1048
|
+
const asSarif = hasFlag('--sarif');
|
|
1049
|
+
const profile = getArg('--profile');
|
|
1050
|
+
let failed = 0;
|
|
1051
|
+
const steps = [];
|
|
1052
|
+
|
|
1053
|
+
const quiet = asJson || asSarif;
|
|
1054
|
+
|
|
1055
|
+
if (!quiet) console.log(C.bold('\n── doctor ──'));
|
|
1056
|
+
const { runDoctor, formatDoctorReport } = await import('./doctor.js');
|
|
1057
|
+
let doctorCwd = target;
|
|
1058
|
+
try {
|
|
1059
|
+
if (existsSync(target) && statSync(target).isFile()) doctorCwd = dirname(target);
|
|
1060
|
+
} catch { /* keep target */ }
|
|
1061
|
+
const doc = await runDoctor({ cwd: doctorCwd, pkgRoot: PKG_ROOT });
|
|
1062
|
+
if (!quiet) console.log(formatDoctorReport(doc));
|
|
1063
|
+
if (!doc.ok) failed += 1;
|
|
1064
|
+
steps.push({ step: 'doctor', ok: doc.ok, detail: { checks: doc.checks?.length, warnings: doc.warnings?.length } });
|
|
1065
|
+
|
|
1066
|
+
if (!quiet) console.log(C.bold('\n── blueprint --strict ──'));
|
|
1067
|
+
const { validateAllBlueprints } = await import('./blueprint.js');
|
|
1068
|
+
const bp = validateAllBlueprints();
|
|
1069
|
+
const badBp = bp.filter((r) => !r.ok);
|
|
1070
|
+
if (badBp.length) {
|
|
1071
|
+
if (!quiet) {
|
|
1072
|
+
for (const r of badBp) console.log(C.red(`${r.id}: ${r.missing?.join(', ') || r.error}`));
|
|
1073
|
+
}
|
|
1074
|
+
failed += 1;
|
|
1075
|
+
} else if (!quiet) {
|
|
1076
|
+
console.log(C.green(`All ${bp.length} blueprints pass --strict`));
|
|
1077
|
+
}
|
|
1078
|
+
steps.push({ step: 'blueprint', ok: badBp.length === 0, total: bp.length, failed: badBp.length });
|
|
1079
|
+
|
|
1080
|
+
if (!quiet) console.log(C.bold('\n── scan ──'));
|
|
1081
|
+
const { scan } = await import('./scanner.js');
|
|
1082
|
+
const scanResult = scan(target, { severity: 'warning', format: 'json', returnData: true });
|
|
1083
|
+
if (!quiet && scanResult.issues?.length) {
|
|
1084
|
+
for (const i of scanResult.issues.slice(0, 40)) {
|
|
1085
|
+
console.log(` ${i.severity} ${i.rule} L${i.line}: ${i.message}`);
|
|
1086
|
+
}
|
|
1087
|
+
if (scanResult.issues.length > 40) console.log(C.dim(` … ${scanResult.issues.length - 40} more`));
|
|
1088
|
+
} else if (!quiet) {
|
|
1089
|
+
console.log(C.green('No scan issues at warning+'));
|
|
1090
|
+
}
|
|
1091
|
+
if (scanResult.exitCode) failed += 1;
|
|
1092
|
+
steps.push({
|
|
1093
|
+
step: 'scan',
|
|
1094
|
+
ok: !scanResult.exitCode,
|
|
1095
|
+
errors: scanResult.errors,
|
|
1096
|
+
warnings: scanResult.warnings,
|
|
1097
|
+
issues: scanResult.issues,
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
let htmlFile = null;
|
|
1101
|
+
let reviewReport = null;
|
|
1102
|
+
try {
|
|
1103
|
+
const st = statSync(target);
|
|
1104
|
+
if (st.isFile() && /\.html?$/i.test(target)) htmlFile = target;
|
|
1105
|
+
else if (st.isDirectory()) {
|
|
1106
|
+
const idx = join(target, 'index.html');
|
|
1107
|
+
if (existsSync(idx)) htmlFile = idx;
|
|
1108
|
+
}
|
|
1109
|
+
} catch { /* skip review */ }
|
|
1110
|
+
|
|
1111
|
+
if (htmlFile) {
|
|
1112
|
+
if (!quiet) console.log(C.bold('\n── review ──'));
|
|
1113
|
+
const { reviewHtml } = await import('./review.js');
|
|
1114
|
+
const html = readFileSync(htmlFile, 'utf-8');
|
|
1115
|
+
reviewReport = reviewHtml(html, { prompt: '', profile: profile || undefined });
|
|
1116
|
+
if (!quiet) {
|
|
1117
|
+
console.log(`Gate: ${reviewReport.gate} (profile ${reviewReport.profile}, promptScore ${reviewReport.promptScore ?? '—'})`);
|
|
1118
|
+
}
|
|
1119
|
+
if (reviewReport.gate === 'fail') failed += 1;
|
|
1120
|
+
steps.push({ step: 'review', ok: reviewReport.gate !== 'fail', gate: reviewReport.gate, report: reviewReport });
|
|
1121
|
+
} else {
|
|
1122
|
+
if (!quiet) console.log(C.dim('\n── review skipped (no index.html / HTML file) ──'));
|
|
1123
|
+
steps.push({ step: 'review', ok: true, skipped: true });
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
const payload = {
|
|
1127
|
+
ok: failed === 0,
|
|
1128
|
+
failedSteps: failed,
|
|
1129
|
+
target,
|
|
1130
|
+
steps,
|
|
1131
|
+
};
|
|
1132
|
+
|
|
1133
|
+
if (asSarif) {
|
|
1134
|
+
const results = [];
|
|
1135
|
+
for (const issue of scanResult.issues || []) {
|
|
1136
|
+
results.push({
|
|
1137
|
+
ruleId: issue.rule,
|
|
1138
|
+
level: issue.severity === 'ERROR' ? 'error' : issue.severity === 'WARNING' ? 'warning' : 'note',
|
|
1139
|
+
message: { text: issue.message },
|
|
1140
|
+
locations: [{
|
|
1141
|
+
physicalLocation: {
|
|
1142
|
+
artifactLocation: { uri: issue.file || htmlFile || target },
|
|
1143
|
+
region: { startLine: issue.line || 1 },
|
|
1144
|
+
},
|
|
1145
|
+
}],
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
for (const issue of reviewReport?.issues || []) {
|
|
1149
|
+
results.push({
|
|
1150
|
+
ruleId: issue.code,
|
|
1151
|
+
level: issue.severity === 'error' ? 'error' : 'warning',
|
|
1152
|
+
message: { text: issue.message },
|
|
1153
|
+
locations: [{
|
|
1154
|
+
physicalLocation: {
|
|
1155
|
+
artifactLocation: { uri: htmlFile || target },
|
|
1156
|
+
region: { startLine: 1 },
|
|
1157
|
+
},
|
|
1158
|
+
}],
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
const sarif = {
|
|
1162
|
+
$schema: 'https://json.schemastore.org/sarif-2.1.0.json',
|
|
1163
|
+
version: '2.1.0',
|
|
1164
|
+
runs: [{
|
|
1165
|
+
tool: { driver: { name: 'velinstyle-check', informationUri: 'https://github.com/SkyliteDesign/velinstyle', version: CLI_VERSION } },
|
|
1166
|
+
results,
|
|
1167
|
+
}],
|
|
1168
|
+
};
|
|
1169
|
+
console.log(JSON.stringify(sarif, null, 2));
|
|
1170
|
+
} else if (asJson) {
|
|
1171
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
1172
|
+
} else if (failed) {
|
|
1173
|
+
console.log(C.red(`\ncheck failed (${failed} step(s))`));
|
|
1174
|
+
} else {
|
|
1175
|
+
console.log(C.green('\ncheck passed'));
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
process.exit(failed ? 1 : 0);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
function suggestCommand(unknown) {
|
|
1182
|
+
const names = [
|
|
1183
|
+
'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',
|
|
1186
|
+
];
|
|
1187
|
+
const q = String(unknown || '').toLowerCase();
|
|
1188
|
+
function editDistance(a, b) {
|
|
1189
|
+
const m = a.length;
|
|
1190
|
+
const n = b.length;
|
|
1191
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
1192
|
+
for (let i = 0; i <= m; i += 1) dp[i][0] = i;
|
|
1193
|
+
for (let j = 0; j <= n; j += 1) dp[0][j] = j;
|
|
1194
|
+
for (let i = 1; i <= m; i += 1) {
|
|
1195
|
+
for (let j = 1; j <= n; j += 1) {
|
|
1196
|
+
dp[i][j] = a[i - 1] === b[j - 1]
|
|
1197
|
+
? dp[i - 1][j - 1]
|
|
1198
|
+
: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
return dp[m][n];
|
|
1202
|
+
}
|
|
1203
|
+
return names
|
|
1204
|
+
.map((name) => ({ name, dist: editDistance(q, name) }))
|
|
1205
|
+
.sort((a, b) => a.dist - b.dist || a.name.localeCompare(b.name))
|
|
1206
|
+
.slice(0, 3)
|
|
1207
|
+
.filter((s) => s.dist <= Math.max(4, Math.ceil(q.length / 2)))
|
|
1208
|
+
.map((s) => s.name);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
function unknownCommand(cmd) {
|
|
1212
|
+
console.log(C.red(`Unknown command '${cmd}'.`));
|
|
1213
|
+
const suggestions = suggestCommand(cmd);
|
|
1214
|
+
if (suggestions.length) {
|
|
1215
|
+
console.log(`Did you mean ${suggestions.map((s) => C.cyan(s)).join(', ')}?`);
|
|
1216
|
+
}
|
|
1217
|
+
console.log(C.dim('Run velinstyle --help for the command list.'));
|
|
1218
|
+
process.exit(1);
|
|
1219
|
+
}
|
|
1220
|
+
|
|
750
1221
|
// ── Router ───────────────────────────────────────────────────────────────────
|
|
751
1222
|
|
|
752
|
-
|
|
1223
|
+
const ALIASES = {
|
|
1224
|
+
validate: 'check',
|
|
1225
|
+
documentation: 'docs',
|
|
1226
|
+
};
|
|
1227
|
+
|
|
1228
|
+
const resolvedCommand = ALIASES[command] || command;
|
|
1229
|
+
|
|
1230
|
+
switch (resolvedCommand) {
|
|
753
1231
|
case 'init': init(); break;
|
|
754
1232
|
case 'build': build(); break;
|
|
755
1233
|
case 'themes': themes(); break;
|
|
756
1234
|
case 'add': add(); break;
|
|
757
1235
|
case 'icons': icons(); break;
|
|
758
1236
|
case 'blueprint': await blueprintCmd(); break;
|
|
1237
|
+
case 'create': await createCmd(); break;
|
|
1238
|
+
case 'serve': await serveCmd(); break;
|
|
1239
|
+
case 'doctor': await doctorCmd(); break;
|
|
1240
|
+
case 'check': await checkCmd(); break;
|
|
759
1241
|
case 'tokens': await tokensCmd(); break;
|
|
760
1242
|
case 'scan': scanCmd(); break;
|
|
761
1243
|
case 'prefix': await prefixCmd(); break;
|
|
762
1244
|
case 'scaffold': await scaffoldCmd(); break;
|
|
1245
|
+
case 'plan': await planCmd(); break;
|
|
1246
|
+
case 'review': await reviewCmd(); break;
|
|
763
1247
|
case 'layout': await layoutCmd(); break;
|
|
764
1248
|
case 'perf': await perfCmd(); break;
|
|
765
1249
|
case 'docs': await docsCmd(); break;
|
|
766
1250
|
case 'meta': await metaCmd(); break;
|
|
767
1251
|
case 'search': await searchCmd(); break;
|
|
768
|
-
case '
|
|
769
|
-
|
|
1252
|
+
case 'skills': await skillsCmd(); break;
|
|
1253
|
+
case 'workflow': await workflowCmd(); break;
|
|
1254
|
+
case 'wc': await wcCmd(); break;
|
|
1255
|
+
case '--help': case '-h': case undefined: help(); break;
|
|
1256
|
+
default: unknownCommand(command); break;
|
|
770
1257
|
}
|