@design-ai/cli 4.55.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/.claude-plugin/plugin.json +164 -0
- package/AGENTS.ko.md +126 -0
- package/AGENTS.md +182 -0
- package/CHANGELOG.md +6883 -0
- package/CLAUDE.md +39 -0
- package/LICENSE +21 -0
- package/README.ko.md +245 -0
- package/README.md +277 -0
- package/agents/README.md +14 -0
- package/agents/a11y-reviewer.md +121 -0
- package/agents/component-architect.md +57 -0
- package/agents/design-critic.md +46 -0
- package/agents/token-extractor.md +63 -0
- package/cli/bin/design-ai-mcp.mjs +6 -0
- package/cli/bin/design-ai.mjs +40 -0
- package/cli/commands/audit.mjs +111 -0
- package/cli/commands/check.mjs +226 -0
- package/cli/commands/doctor.mjs +141 -0
- package/cli/commands/examples.mjs +58 -0
- package/cli/commands/help.mjs +271 -0
- package/cli/commands/install.mjs +161 -0
- package/cli/commands/learn.mjs +1871 -0
- package/cli/commands/list.mjs +143 -0
- package/cli/commands/mcp.mjs +27 -0
- package/cli/commands/pack.mjs +211 -0
- package/cli/commands/prompt.mjs +199 -0
- package/cli/commands/route.mjs +247 -0
- package/cli/commands/search.mjs +60 -0
- package/cli/commands/show.mjs +52 -0
- package/cli/commands/site.mjs +558 -0
- package/cli/commands/status.mjs +161 -0
- package/cli/commands/uninstall.mjs +119 -0
- package/cli/commands/update.mjs +184 -0
- package/cli/commands/version.mjs +94 -0
- package/cli/commands/workspace.mjs +176 -0
- package/cli/lib/brief.mjs +52 -0
- package/cli/lib/check.mjs +642 -0
- package/cli/lib/dispatch.mjs +109 -0
- package/cli/lib/doctor.mjs +505 -0
- package/cli/lib/examples.mjs +258 -0
- package/cli/lib/exec.mjs +63 -0
- package/cli/lib/help-flags.mjs +5 -0
- package/cli/lib/learn.mjs +3694 -0
- package/cli/lib/log.mjs +47 -0
- package/cli/lib/mcp-server.mjs +426 -0
- package/cli/lib/output.mjs +101 -0
- package/cli/lib/pack.mjs +599 -0
- package/cli/lib/paths.mjs +63 -0
- package/cli/lib/prompt.mjs +603 -0
- package/cli/lib/route.mjs +740 -0
- package/cli/lib/search.mjs +158 -0
- package/cli/lib/show.mjs +161 -0
- package/cli/lib/signals.mjs +2337 -0
- package/cli/lib/site.mjs +6617 -0
- package/cli/lib/skill-proposals.mjs +2046 -0
- package/cli/lib/suggest.mjs +66 -0
- package/cli/lib/workspace.mjs +1056 -0
- package/commands/README.md +25 -0
- package/commands/component-spec.md +34 -0
- package/commands/conversational.md +44 -0
- package/commands/design-from-brief.md +141 -0
- package/commands/design-review.md +62 -0
- package/commands/document-from-brief.md +47 -0
- package/commands/extract-tokens.md +38 -0
- package/commands/game-ui.md +40 -0
- package/commands/illustration.md +37 -0
- package/commands/iterate.md +167 -0
- package/commands/motion-design.md +54 -0
- package/commands/palette-from-brand.md +50 -0
- package/commands/print.md +49 -0
- package/commands/slide-deck.md +46 -0
- package/commands/spatial.md +47 -0
- package/commands/stability-review.md +74 -0
- package/commands/video.md +42 -0
- package/commands/website-improvement.md +77 -0
- package/docs/AGENT-DEVELOPMENT.md +658 -0
- package/docs/AI-LEARNING.md +429 -0
- package/docs/AIDER-INTEGRATION.md +224 -0
- package/docs/ARCHITECTURE.ko.md +183 -0
- package/docs/ARCHITECTURE.md +105 -0
- package/docs/CODEX-INTEGRATION.md +311 -0
- package/docs/COMPANY-WEBSITE-DOGFOOD.ko.md +144 -0
- package/docs/COMPANY-WEBSITE-DOGFOOD.md +150 -0
- package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.ko.md +153 -0
- package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.md +154 -0
- package/docs/CONTRIBUTING.ko.md +203 -0
- package/docs/CONTRIBUTING.md +242 -0
- package/docs/CURSOR-INTEGRATION.md +220 -0
- package/docs/DISTRIBUTION.ko.md +248 -0
- package/docs/DISTRIBUTION.md +253 -0
- package/docs/DOGFOOD-FINDINGS.md +180 -0
- package/docs/DOGFOOD-V4-FINDINGS.md +139 -0
- package/docs/DOGFOOD-V4-MKDOCS-FINDINGS.md +233 -0
- package/docs/DOGFOOD-V4-NPM-FINDINGS.md +157 -0
- package/docs/DOGFOOD-V4-VSCODE-FINDINGS.md +135 -0
- package/docs/FIGMA-INTEGRATION.md +222 -0
- package/docs/MCP-INTEGRATION.md +243 -0
- package/docs/MIGRATION-v4.md +121 -0
- package/docs/PLUGIN-PACKAGING.md +240 -0
- package/docs/PRODUCT-READINESS.md +66 -0
- package/docs/QUICKSTART.ko.md +178 -0
- package/docs/QUICKSTART.md +179 -0
- package/docs/RELEASE-CHECKLIST.md +292 -0
- package/docs/ROADMAP.md +19495 -0
- package/docs/SESSION-LOG.md +940 -0
- package/docs/TOKEN-SYNC.md +237 -0
- package/docs/USING.ko.md +206 -0
- package/docs/USING.md +218 -0
- package/docs/WEBSITE-IMPROVEMENT.ko.md +75 -0
- package/docs/WEBSITE-IMPROVEMENT.md +89 -0
- package/docs/announcements/README.md +56 -0
- package/docs/announcements/dev-to-korea.md +206 -0
- package/docs/announcements/hashnode-post.ko.md +232 -0
- package/docs/announcements/okky-post.ko.md +158 -0
- package/docs/announcements/press-kit.md +101 -0
- package/docs/announcements/reddit-r-korea.md +196 -0
- package/docs/announcements/show-hn.md +114 -0
- package/docs/announcements/twitter-thread.md +255 -0
- package/docs/external-status.md +34 -0
- package/docs/integrations/aider-walkthrough.ko.md +275 -0
- package/docs/integrations/aider-walkthrough.md +274 -0
- package/docs/integrations/codex-walkthrough.ko.md +297 -0
- package/docs/integrations/codex-walkthrough.md +297 -0
- package/docs/integrations/cursor-walkthrough.ko.md +281 -0
- package/docs/integrations/cursor-walkthrough.md +284 -0
- package/docs/integrations/design-ai-mcp-server.md +169 -0
- package/docs/integrations/figma-mcp.md +149 -0
- package/docs/integrations/github-mcp.md +178 -0
- package/docs/integrations/linear-mcp.md +215 -0
- package/docs/integrations/notion-mcp.md +174 -0
- package/docs/integrations/sdk-walkthrough.ko.md +375 -0
- package/docs/integrations/sdk-walkthrough.md +375 -0
- package/docs/integrations/slack-mcp.md +208 -0
- package/docs/integrations/vscode-walkthrough.ko.md +202 -0
- package/docs/integrations/vscode-walkthrough.md +205 -0
- package/docs/requirements.txt +16 -0
- package/docs/site-overrides/extra.css +83 -0
- package/docs/site-overrides/favicon.svg +4 -0
- package/docs/site-overrides/logo.svg +10 -0
- package/docs/site-overrides/main.html +18 -0
- package/docs/website-console/app.js +2540 -0
- package/docs/website-console/index.html +24 -0
- package/docs/website-console/styles.css +975 -0
- package/examples/README.md +252 -0
- package/examples/cases/dogfood-v4-korean-hr-onboarding.md +356 -0
- package/examples/component-accordion-actions.md +153 -0
- package/examples/component-accordion-details.md +147 -0
- package/examples/component-accordion-summary.md +180 -0
- package/examples/component-accordion.md +229 -0
- package/examples/component-account-card.md +284 -0
- package/examples/component-address-input.md +260 -0
- package/examples/component-affix.md +190 -0
- package/examples/component-alert-dialog.md +210 -0
- package/examples/component-alert-title.md +77 -0
- package/examples/component-alert.md +192 -0
- package/examples/component-amount-input.md +278 -0
- package/examples/component-anchor.md +198 -0
- package/examples/component-app-bar.md +249 -0
- package/examples/component-aspect-ratio.md +156 -0
- package/examples/component-auto-complete.md +199 -0
- package/examples/component-avatar-group.md +170 -0
- package/examples/component-avatar.md +191 -0
- package/examples/component-back-top.md +123 -0
- package/examples/component-backdrop.md +148 -0
- package/examples/component-badge.md +181 -0
- package/examples/component-banner.md +237 -0
- package/examples/component-biometric-gate.md +281 -0
- package/examples/component-blockquote.md +153 -0
- package/examples/component-border-beam.md +207 -0
- package/examples/component-bottom-navigation.md +226 -0
- package/examples/component-box.md +112 -0
- package/examples/component-breadcrumb.md +222 -0
- package/examples/component-button-base.md +190 -0
- package/examples/component-button-group.md +117 -0
- package/examples/component-button.md +213 -0
- package/examples/component-calendar.md +280 -0
- package/examples/component-callout.md +131 -0
- package/examples/component-card-actions.md +101 -0
- package/examples/component-card-content.md +90 -0
- package/examples/component-card-header.md +122 -0
- package/examples/component-card-media.md +79 -0
- package/examples/component-card.md +233 -0
- package/examples/component-carousel.md +266 -0
- package/examples/component-cascader.md +135 -0
- package/examples/component-category-picker.md +271 -0
- package/examples/component-chart.md +237 -0
- package/examples/component-chat-interface.md +399 -0
- package/examples/component-checkbox.md +149 -0
- package/examples/component-click-away-listener.md +87 -0
- package/examples/component-code.md +213 -0
- package/examples/component-collapsible.md +219 -0
- package/examples/component-color-picker.md +110 -0
- package/examples/component-combobox.md +267 -0
- package/examples/component-command.md +299 -0
- package/examples/component-config-provider.md +190 -0
- package/examples/component-context-menu.md +179 -0
- package/examples/component-css-baseline.md +148 -0
- package/examples/component-date-picker.md +249 -0
- package/examples/component-descriptions.md +242 -0
- package/examples/component-dialog-actions.md +111 -0
- package/examples/component-dialog-content-text.md +76 -0
- package/examples/component-dialog-content.md +105 -0
- package/examples/component-dialog-title.md +104 -0
- package/examples/component-dialog.md +176 -0
- package/examples/component-divider.md +182 -0
- package/examples/component-doc-page.md +217 -0
- package/examples/component-drawer.md +257 -0
- package/examples/component-dropdown.md +220 -0
- package/examples/component-email-layout.md +253 -0
- package/examples/component-empty-state.md +269 -0
- package/examples/component-empty.md +172 -0
- package/examples/component-fade.md +87 -0
- package/examples/component-feature-grid.md +201 -0
- package/examples/component-field.md +266 -0
- package/examples/component-filled-input.md +114 -0
- package/examples/component-flex.md +117 -0
- package/examples/component-float-button.md +214 -0
- package/examples/component-form-control-label.md +134 -0
- package/examples/component-form-control.md +113 -0
- package/examples/component-form-controls.md +251 -0
- package/examples/component-form-group.md +86 -0
- package/examples/component-form-helper-text.md +95 -0
- package/examples/component-form-label.md +98 -0
- package/examples/component-form.md +291 -0
- package/examples/component-game-hud.md +362 -0
- package/examples/component-game-menu.md +327 -0
- package/examples/component-grid.md +140 -0
- package/examples/component-grow.md +79 -0
- package/examples/component-hero-block.md +252 -0
- package/examples/component-hover-card.md +211 -0
- package/examples/component-icon-button.md +142 -0
- package/examples/component-icon.md +102 -0
- package/examples/component-illustration.md +280 -0
- package/examples/component-image-list.md +107 -0
- package/examples/component-image.md +282 -0
- package/examples/component-input-adornment.md +101 -0
- package/examples/component-input-base.md +134 -0
- package/examples/component-input-number.md +141 -0
- package/examples/component-input-otp.md +271 -0
- package/examples/component-input.md +213 -0
- package/examples/component-item.md +243 -0
- package/examples/component-kbd.md +197 -0
- package/examples/component-krw-amount.md +219 -0
- package/examples/component-label.md +118 -0
- package/examples/component-layout.md +217 -0
- package/examples/component-link.md +223 -0
- package/examples/component-list-item-avatar.md +72 -0
- package/examples/component-list-item-button.md +139 -0
- package/examples/component-list-item-icon.md +82 -0
- package/examples/component-list-item-text.md +98 -0
- package/examples/component-list-item.md +116 -0
- package/examples/component-list-subheader.md +70 -0
- package/examples/component-list.md +198 -0
- package/examples/component-loading-button.md +125 -0
- package/examples/component-loading-sequence.md +254 -0
- package/examples/component-lottie-player.md +279 -0
- package/examples/component-masonry.md +191 -0
- package/examples/component-mentions.md +189 -0
- package/examples/component-menu-item.md +102 -0
- package/examples/component-menu-list.md +98 -0
- package/examples/component-menu.md +139 -0
- package/examples/component-menubar.md +259 -0
- package/examples/component-message.md +162 -0
- package/examples/component-mobile-stepper.md +155 -0
- package/examples/component-modal.md +220 -0
- package/examples/component-navigation-menu.md +295 -0
- package/examples/component-notification.md +166 -0
- package/examples/component-otp-countdown.md +245 -0
- package/examples/component-outlined-input.md +145 -0
- package/examples/component-page-transition.md +281 -0
- package/examples/component-pagination.md +226 -0
- package/examples/component-paper.md +199 -0
- package/examples/component-pass-auth.md +265 -0
- package/examples/component-payment-brand-button.md +253 -0
- package/examples/component-payment-method-selector.md +272 -0
- package/examples/component-payment-receipt.md +277 -0
- package/examples/component-popconfirm.md +144 -0
- package/examples/component-popover.md +239 -0
- package/examples/component-popper.md +129 -0
- package/examples/component-pricing-cards.md +247 -0
- package/examples/component-progress.md +195 -0
- package/examples/component-qr-code.md +201 -0
- package/examples/component-radio.md +167 -0
- package/examples/component-rate.md +202 -0
- package/examples/component-resizable.md +163 -0
- package/examples/component-result.md +270 -0
- package/examples/component-scroll-area.md +199 -0
- package/examples/component-scroll-reveal.md +320 -0
- package/examples/component-segmented.md +178 -0
- package/examples/component-select.md +258 -0
- package/examples/component-separator.md +177 -0
- package/examples/component-sheet.md +277 -0
- package/examples/component-sidebar.md +257 -0
- package/examples/component-skeleton.md +178 -0
- package/examples/component-slide.md +89 -0
- package/examples/component-slider.md +208 -0
- package/examples/component-snackbar-content.md +92 -0
- package/examples/component-snackbar.md +121 -0
- package/examples/component-sonner.md +165 -0
- package/examples/component-space.md +125 -0
- package/examples/component-spatial-locomotion.md +373 -0
- package/examples/component-spatial-panel.md +330 -0
- package/examples/component-speed-dial-action.md +78 -0
- package/examples/component-speed-dial.md +177 -0
- package/examples/component-spin.md +173 -0
- package/examples/component-spinner.md +204 -0
- package/examples/component-splitter.md +210 -0
- package/examples/component-stack.md +130 -0
- package/examples/component-statistic.md +282 -0
- package/examples/component-step-button.md +157 -0
- package/examples/component-step-connector.md +157 -0
- package/examples/component-step-content.md +121 -0
- package/examples/component-step-icon.md +115 -0
- package/examples/component-step-label.md +101 -0
- package/examples/component-step.md +84 -0
- package/examples/component-steps.md +264 -0
- package/examples/component-stock-chart.md +251 -0
- package/examples/component-swipeable-drawer.md +149 -0
- package/examples/component-switch.md +99 -0
- package/examples/component-tab-scroll-button.md +180 -0
- package/examples/component-tab.md +120 -0
- package/examples/component-table-body.md +82 -0
- package/examples/component-table-cell.md +118 -0
- package/examples/component-table-container.md +75 -0
- package/examples/component-table-footer.md +72 -0
- package/examples/component-table-head.md +78 -0
- package/examples/component-table-pagination.md +137 -0
- package/examples/component-table-row.md +113 -0
- package/examples/component-table-sort-label.md +109 -0
- package/examples/component-table.md +202 -0
- package/examples/component-tabs.md +184 -0
- package/examples/component-tag-badge.md +309 -0
- package/examples/component-tag.md +102 -0
- package/examples/component-testimonial-carousel.md +218 -0
- package/examples/component-textarea-autosize.md +114 -0
- package/examples/component-textarea.md +173 -0
- package/examples/component-time-picker.md +205 -0
- package/examples/component-timeline.md +170 -0
- package/examples/component-toast.md +224 -0
- package/examples/component-toggle-button.md +129 -0
- package/examples/component-toggle.md +220 -0
- package/examples/component-toolbar.md +104 -0
- package/examples/component-tooltip.md +178 -0
- package/examples/component-tour.md +176 -0
- package/examples/component-transaction-list-item.md +243 -0
- package/examples/component-transfer.md +156 -0
- package/examples/component-tree-select.md +202 -0
- package/examples/component-tree.md +297 -0
- package/examples/component-typography.md +215 -0
- package/examples/component-upload.md +295 -0
- package/examples/component-video-hero.md +409 -0
- package/examples/component-video-player.md +340 -0
- package/examples/component-voice-input.md +408 -0
- package/examples/component-watermark.md +217 -0
- package/examples/component-zoom.md +92 -0
- package/examples/doc-explanation-example.md +196 -0
- package/examples/doc-how-to-example.md +205 -0
- package/examples/doc-tutorial-example.md +162 -0
- package/examples/dogfood-korean-fintech-system.md +433 -0
- package/examples/email-transactional-example.md +259 -0
- package/examples/palette-saas-violet.md +235 -0
- package/examples/print-business-card-spec.md +205 -0
- package/examples/print-packaging-spec.md +285 -0
- package/examples/report-example.md +228 -0
- package/examples/slide-deck-example.md +237 -0
- package/examples/website-improvement-report.md +128 -0
- package/examples/website-improvement-workspace.json +126 -0
- package/install.sh +189 -0
- package/knowledge/COVERAGE.md +740 -0
- package/knowledge/PRINCIPLES.md +108 -0
- package/knowledge/a11y/contrast.md +70 -0
- package/knowledge/a11y/keyboard-and-focus.md +108 -0
- package/knowledge/colors/color-theory.md +90 -0
- package/knowledge/colors/mui-palette-structure.md +105 -0
- package/knowledge/colors/palettes-by-product-type.md +876 -0
- package/knowledge/components/INDEX.md +231 -0
- package/knowledge/components/index.json +1470 -0
- package/knowledge/components/shadcn-registry.md +159 -0
- package/knowledge/conversational/ai-chat-interfaces.md +323 -0
- package/knowledge/conversational/chatbot-design.md +312 -0
- package/knowledge/conversational/conversational-ui-fundamentals.md +299 -0
- package/knowledge/conversational/korean-voice-conventions.md +281 -0
- package/knowledge/conversational/voice-ui-patterns.md +297 -0
- package/knowledge/design-tokens/ant-design.md +124 -0
- package/knowledge/design-tokens/material-3.md +235 -0
- package/knowledge/design-tokens/polaris-and-carbon.md +231 -0
- package/knowledge/design-tokens/tailwind-v4.md +284 -0
- package/knowledge/game-ui/game-accessibility.md +317 -0
- package/knowledge/game-ui/game-ui-fundamentals.md +281 -0
- package/knowledge/game-ui/hud-design.md +324 -0
- package/knowledge/game-ui/korean-gaming-conventions.md +312 -0
- package/knowledge/game-ui/menu-systems.md +388 -0
- package/knowledge/i18n/korean-app-store-visual.md +223 -0
- package/knowledge/i18n/korean-document-style.md +301 -0
- package/knowledge/i18n/korean-payments.md +211 -0
- package/knowledge/i18n/korean-product-conventions.md +96 -0
- package/knowledge/i18n/korean-publishing.md +139 -0
- package/knowledge/i18n/korean-typography.md +123 -0
- package/knowledge/icons/curated-sets.md +225 -0
- package/knowledge/illustration/hero-illustrations.md +234 -0
- package/knowledge/illustration/illustration-systems.md +221 -0
- package/knowledge/illustration/mascot-design.md +208 -0
- package/knowledge/illustration/spot-illustrations.md +246 -0
- package/knowledge/illustration/svg-optimization.md +308 -0
- package/knowledge/layout/spacing-and-grid.md +119 -0
- package/knowledge/motion/app-loading-sequences.md +277 -0
- package/knowledge/motion/choreography-depth.md +297 -0
- package/knowledge/motion/marketing-motion.md +223 -0
- package/knowledge/motion/micro-interactions.md +266 -0
- package/knowledge/motion/motion-tools.md +281 -0
- package/knowledge/motion/principles.md +126 -0
- package/knowledge/patterns/auth-flow-design.md +316 -0
- package/knowledge/patterns/b2b-onboarding-flows.md +182 -0
- package/knowledge/patterns/brand-identity.md +238 -0
- package/knowledge/patterns/brand-references.md +97 -0
- package/knowledge/patterns/chart-color-encoding.md +269 -0
- package/knowledge/patterns/chart-types.md +344 -0
- package/knowledge/patterns/dashboard-composition.md +299 -0
- package/knowledge/patterns/design-system-qa.md +356 -0
- package/knowledge/patterns/document-typography.md +248 -0
- package/knowledge/patterns/email-design.md +338 -0
- package/knowledge/patterns/empty-states.md +263 -0
- package/knowledge/patterns/error-states.md +318 -0
- package/knowledge/patterns/form-design.md +237 -0
- package/knowledge/patterns/information-architecture.md +341 -0
- package/knowledge/patterns/landing-hero-design.md +283 -0
- package/knowledge/patterns/landing-page-patterns.md +681 -0
- package/knowledge/patterns/list-and-feed.md +371 -0
- package/knowledge/patterns/mobile-navigation.md +278 -0
- package/knowledge/patterns/money-and-amount.md +301 -0
- package/knowledge/patterns/onboarding.md +300 -0
- package/knowledge/patterns/pricing-page-design.md +261 -0
- package/knowledge/patterns/realtime-data.md +280 -0
- package/knowledge/patterns/report-design.md +330 -0
- package/knowledge/patterns/search-ux.md +373 -0
- package/knowledge/patterns/settings-page.md +325 -0
- package/knowledge/patterns/slide-deck-design.md +316 -0
- package/knowledge/patterns/styles-catalog.md +2599 -0
- package/knowledge/patterns/technical-writing.md +306 -0
- package/knowledge/patterns/ui-reasoning.md +1853 -0
- package/knowledge/patterns/ux-guidelines.md +1454 -0
- package/knowledge/platforms/react-native.md +395 -0
- package/knowledge/print/brochures-and-flyers.md +276 -0
- package/knowledge/print/korean-print-conventions.md +284 -0
- package/knowledge/print/packaging.md +321 -0
- package/knowledge/print/print-fundamentals.md +238 -0
- package/knowledge/print/signage-and-posters.md +235 -0
- package/knowledge/print/stationery.md +262 -0
- package/knowledge/spatial/ar-patterns.md +253 -0
- package/knowledge/spatial/comfort-and-accessibility.md +245 -0
- package/knowledge/spatial/spatial-design-fundamentals.md +346 -0
- package/knowledge/spatial/spatial-ui-elements.md +343 -0
- package/knowledge/spatial/vr-patterns.md +302 -0
- package/knowledge/typography/font-pairings.md +332 -0
- package/knowledge/typography/mui-type-scale.md +57 -0
- package/knowledge/typography/type-scale-fundamentals.md +105 -0
- package/knowledge/video/in-product-video.md +277 -0
- package/knowledge/video/korean-video-conventions.md +247 -0
- package/knowledge/video/marketing-video.md +258 -0
- package/knowledge/video/social-and-short-form.md +257 -0
- package/knowledge/video/video-fundamentals.md +296 -0
- package/package.json +106 -0
- package/skills/README.md +39 -0
- package/skills/color-palette/PLAYBOOK.md +175 -0
- package/skills/color-palette/SKILL.md +6 -0
- package/skills/color-palette/TEMPLATE.md +103 -0
- package/skills/component-spec-writer/PLAYBOOK.md +169 -0
- package/skills/component-spec-writer/SKILL.md +6 -0
- package/skills/component-spec-writer/TEMPLATE.md +115 -0
- package/skills/conversational-ui-designer/PLAYBOOK.md +231 -0
- package/skills/conversational-ui-designer/SKILL.md +6 -0
- package/skills/design-broadcast/PLAYBOOK.md +146 -0
- package/skills/design-broadcast/SKILL.md +6 -0
- package/skills/design-critique/PLAYBOOK.md +137 -0
- package/skills/design-critique/SKILL.md +6 -0
- package/skills/design-pr-review/PLAYBOOK.md +171 -0
- package/skills/design-pr-review/SKILL.md +6 -0
- package/skills/design-system-builder/PLAYBOOK.md +218 -0
- package/skills/design-system-builder/SKILL.md +6 -0
- package/skills/design-system-qa/PLAYBOOK.md +163 -0
- package/skills/design-system-qa/SKILL.md +6 -0
- package/skills/document-author/PLAYBOOK.md +167 -0
- package/skills/document-author/SKILL.md +6 -0
- package/skills/figma-token-sync/PLAYBOOK.md +149 -0
- package/skills/figma-token-sync/SKILL.md +6 -0
- package/skills/game-ui-designer/PLAYBOOK.md +209 -0
- package/skills/game-ui-designer/SKILL.md +6 -0
- package/skills/handoff-spec/PLAYBOOK.md +170 -0
- package/skills/handoff-spec/SKILL.md +6 -0
- package/skills/illustration-designer/PLAYBOOK.md +166 -0
- package/skills/illustration-designer/SKILL.md +6 -0
- package/skills/motion-designer/PLAYBOOK.md +223 -0
- package/skills/motion-designer/SKILL.md +6 -0
- package/skills/print-designer/PLAYBOOK.md +209 -0
- package/skills/print-designer/SKILL.md +6 -0
- package/skills/slide-deck-author/PLAYBOOK.md +198 -0
- package/skills/slide-deck-author/SKILL.md +6 -0
- package/skills/spatial-designer/PLAYBOOK.md +238 -0
- package/skills/spatial-designer/SKILL.md +6 -0
- package/skills/ux-audit/PLAYBOOK.md +142 -0
- package/skills/ux-audit/SKILL.md +6 -0
- package/skills/video-designer/PLAYBOOK.md +240 -0
- package/skills/video-designer/SKILL.md +6 -0
- package/skills/website-improvement/PLAYBOOK.md +118 -0
- package/skills/website-improvement/SKILL.md +6 -0
- package/skills/website-improvement/TEMPLATE.md +103 -0
- package/tools/audit/changelog-generate.py +176 -0
- package/tools/audit/check-coverage.py +483 -0
- package/tools/audit/doctor_assertions.py +256 -0
- package/tools/audit/example-qa.py +108 -0
- package/tools/audit/frontmatter-check.py +199 -0
- package/tools/audit/integration-check.py +95 -0
- package/tools/audit/korean-copy-check.py +161 -0
- package/tools/audit/link-check.py +146 -0
- package/tools/audit/local-ci.py +558 -0
- package/tools/audit/package-contents.py +723 -0
- package/tools/audit/package-smoke.py +22443 -0
- package/tools/audit/raw-hex-check.py +252 -0
- package/tools/audit/registry-smoke.py +8188 -0
- package/tools/audit/release-metadata.py +9832 -0
- package/tools/audit/run-all.py +351 -0
- package/tools/audit/smoke_assertions.py +12742 -0
- package/tools/audit/stability-review.py +332 -0
- package/tools/audit/stale-check.py +156 -0
- package/tools/migrations/add-version-frontmatter.py +132 -0
- package/tools/migrations/bump-last-updated.py +131 -0
- package/tools/migrations/promote-stability.py +172 -0
- package/tools/preview/README.md +58 -0
- package/tools/preview/render-tokens.py +454 -0
|
@@ -0,0 +1,642 @@
|
|
|
1
|
+
// Generated artifact quality checks for `design-ai check`.
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
readFileSync,
|
|
5
|
+
} from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
|
|
8
|
+
import { listExamples } from "./examples.mjs";
|
|
9
|
+
import { captureLearningEntries } from "./learn.mjs";
|
|
10
|
+
import { assertKnownRouteId, ROUTES } from "./route.mjs";
|
|
11
|
+
import { unknownOptionMessage } from "./suggest.mjs";
|
|
12
|
+
|
|
13
|
+
const DEFAULT_EXAMPLE_LIMIT = 3;
|
|
14
|
+
const CHECK_OPTIONS = [
|
|
15
|
+
"-h",
|
|
16
|
+
"--help",
|
|
17
|
+
"--stdin",
|
|
18
|
+
"--examples",
|
|
19
|
+
"--all-routes",
|
|
20
|
+
"--issues-only",
|
|
21
|
+
"--strict",
|
|
22
|
+
"--route",
|
|
23
|
+
"--limit",
|
|
24
|
+
"--json",
|
|
25
|
+
"--learn",
|
|
26
|
+
"--yes",
|
|
27
|
+
"--learning-file",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export function parseCheckArgs(args) {
|
|
31
|
+
const out = {
|
|
32
|
+
target: "",
|
|
33
|
+
stdin: false,
|
|
34
|
+
examples: false,
|
|
35
|
+
allRoutes: false,
|
|
36
|
+
issuesOnly: false,
|
|
37
|
+
limit: DEFAULT_EXAMPLE_LIMIT,
|
|
38
|
+
strict: false,
|
|
39
|
+
routeId: "",
|
|
40
|
+
json: false,
|
|
41
|
+
learn: false,
|
|
42
|
+
yes: false,
|
|
43
|
+
learningFilePath: "",
|
|
44
|
+
help: false,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
48
|
+
const arg = args[i];
|
|
49
|
+
if (arg === "-h" || arg === "--help") {
|
|
50
|
+
out.help = true;
|
|
51
|
+
} else if (arg === "--stdin") {
|
|
52
|
+
out.stdin = true;
|
|
53
|
+
} else if (arg === "--examples") {
|
|
54
|
+
out.examples = true;
|
|
55
|
+
} else if (arg === "--all-routes") {
|
|
56
|
+
out.allRoutes = true;
|
|
57
|
+
} else if (arg === "--issues-only") {
|
|
58
|
+
out.issuesOnly = true;
|
|
59
|
+
} else if (arg === "--strict") {
|
|
60
|
+
out.strict = true;
|
|
61
|
+
} else if (arg === "--learn") {
|
|
62
|
+
out.learn = true;
|
|
63
|
+
} else if (arg === "--yes") {
|
|
64
|
+
out.yes = true;
|
|
65
|
+
} else if (arg === "--learning-file") {
|
|
66
|
+
const learningFilePath = args[i + 1];
|
|
67
|
+
if (!learningFilePath || learningFilePath.startsWith("--")) throw new Error("--learning-file expects a path");
|
|
68
|
+
out.learningFilePath = learningFilePath;
|
|
69
|
+
i += 1;
|
|
70
|
+
} else if (arg === "--route") {
|
|
71
|
+
const routeId = args[i + 1];
|
|
72
|
+
if (!routeId || routeId.startsWith("--")) throw new Error("--route expects a route id");
|
|
73
|
+
out.routeId = routeId;
|
|
74
|
+
i += 1;
|
|
75
|
+
} else if (arg === "--limit") {
|
|
76
|
+
const limit = Number(args[i + 1]);
|
|
77
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 25) {
|
|
78
|
+
throw new Error("--limit expects an integer from 1 to 25");
|
|
79
|
+
}
|
|
80
|
+
out.limit = limit;
|
|
81
|
+
i += 1;
|
|
82
|
+
} else if (arg === "--json") {
|
|
83
|
+
out.json = true;
|
|
84
|
+
} else if (arg.startsWith("--")) {
|
|
85
|
+
throw new Error(unknownOptionMessage("check", arg, CHECK_OPTIONS));
|
|
86
|
+
} else if (!out.target) {
|
|
87
|
+
out.target = arg;
|
|
88
|
+
} else {
|
|
89
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (out.stdin && out.target) {
|
|
94
|
+
throw new Error("Use either a file path or --stdin, not both");
|
|
95
|
+
}
|
|
96
|
+
if (out.examples && (out.target || out.stdin)) {
|
|
97
|
+
throw new Error("Use --examples by itself, not with a file path or --stdin");
|
|
98
|
+
}
|
|
99
|
+
if (out.examples && out.learn) {
|
|
100
|
+
throw new Error("--learn is only supported for a single artifact file or --stdin, not --examples");
|
|
101
|
+
}
|
|
102
|
+
if (out.allRoutes && !out.examples) {
|
|
103
|
+
throw new Error("--all-routes is only supported with --examples");
|
|
104
|
+
}
|
|
105
|
+
if (out.examples && !out.routeId && !out.allRoutes) {
|
|
106
|
+
throw new Error("--examples requires --route id or --all-routes");
|
|
107
|
+
}
|
|
108
|
+
if (out.routeId && out.allRoutes) {
|
|
109
|
+
throw new Error("Use either --route id or --all-routes, not both");
|
|
110
|
+
}
|
|
111
|
+
if (!out.examples && out.limit !== DEFAULT_EXAMPLE_LIMIT) {
|
|
112
|
+
throw new Error("--limit is only supported with --examples");
|
|
113
|
+
}
|
|
114
|
+
if (out.yes && !out.learn) {
|
|
115
|
+
throw new Error("--yes requires --learn");
|
|
116
|
+
}
|
|
117
|
+
if (out.learningFilePath && !out.learn) {
|
|
118
|
+
throw new Error("--learning-file requires --learn");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function has(pattern, content) {
|
|
125
|
+
return pattern.test(content);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function hasAny(patterns, content) {
|
|
129
|
+
return patterns.some((pattern) => has(pattern, content));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function result({ id, title, passed, severity, passMessage, failMessage, evidence = "" }) {
|
|
133
|
+
return {
|
|
134
|
+
id,
|
|
135
|
+
title,
|
|
136
|
+
level: passed ? "pass" : severity,
|
|
137
|
+
passed,
|
|
138
|
+
message: passed ? passMessage : failMessage,
|
|
139
|
+
...(evidence ? { evidence } : {}),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const ROUTE_REQUIREMENTS = {
|
|
144
|
+
"design-review": [
|
|
145
|
+
{
|
|
146
|
+
id: "review-findings",
|
|
147
|
+
title: "Design review finding structure",
|
|
148
|
+
required: [
|
|
149
|
+
{ label: "issue or finding", patterns: [/\b(issue|finding|problem|risk)\b/i, /문제|리스크|이슈/] },
|
|
150
|
+
{ label: "severity or priority", patterns: [/\b(severity|priority|impact|p[0-3])\b/i, /심각도|우선순위|영향/] },
|
|
151
|
+
{ label: "recommended fix", patterns: [/\b(fix|recommend|change|adjust|replace)\b/i, /수정|개선|권장|제안/] },
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
"website-improvement": [
|
|
156
|
+
{
|
|
157
|
+
id: "website-control-tower",
|
|
158
|
+
title: "Website improvement control tower coverage",
|
|
159
|
+
required: [
|
|
160
|
+
{ label: "Site Profile", patterns: [/\bsite profile\b/i, /사이트.*프로필/] },
|
|
161
|
+
{ label: "Audit Checklist", patterns: [/\baudit checklist\b|\baudit summary\b/i, /감사.*체크리스트|진단.*요약/] },
|
|
162
|
+
{ label: "MCP readiness", patterns: [/\bmcp\b.*\b(required|optional|unused|unavailable|readiness)\b/i, /MCP.*(필수|선택|미사용|불가|준비)/] },
|
|
163
|
+
{ label: "Refactor Plan", patterns: [/\brefactor plan\b|\bpriority improvement plan\b/i, /리팩터.*계획|개선.*계획/] },
|
|
164
|
+
{ label: "Handoff Report", patterns: [/\bhandoff report\b|\bverification results\b/i, /핸드오프.*리포트|검증.*결과/] },
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
id: "website-mvp-boundary",
|
|
169
|
+
title: "Website improvement MVP boundary",
|
|
170
|
+
required: [
|
|
171
|
+
{ label: "target repo boundary", patterns: [/\btarget (website )?repo(?:sitory)?\b|\bnot in design-ai\b/i, /대상.*레포|design-ai.*수정.*아님/] },
|
|
172
|
+
{ label: "no automatic crawling or external writes", patterns: [/\b(no|not|without).*(crawl|external writes|mcp writes|automatic)/i, /자동.*크롤|외부.*쓰기|MCP.*쓰기/] },
|
|
173
|
+
{ label: "no model training", patterns: [/\b(no|not|without).*(model training|fine-tuning|embeddings)\b/i, /모델.*학습|파인튜닝|임베딩/] },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
"design-from-brief": [
|
|
178
|
+
{
|
|
179
|
+
id: "design-system-foundation",
|
|
180
|
+
title: "Design-system foundation coverage",
|
|
181
|
+
required: [
|
|
182
|
+
{ label: "design tokens", patterns: [/\btoken/i, /토큰/] },
|
|
183
|
+
{ label: "component baseline", patterns: [/\bcomponent/i, /컴포넌트/] },
|
|
184
|
+
{ label: "handoff or implementation", patterns: [/\b(handoff|implementation|developer|engineering)\b/i, /핸드오프|구현|개발/] },
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
"component-spec": [
|
|
189
|
+
{
|
|
190
|
+
id: "component-contract",
|
|
191
|
+
title: "Component contract coverage",
|
|
192
|
+
required: [
|
|
193
|
+
{ label: "anatomy or slots", patterns: [/\b(anatomy|structure|slot)\b/i, /구조|슬롯/] },
|
|
194
|
+
{ label: "variants or states", patterns: [/\b(variant|state|disabled|hover|active)\b/i, /변형|상태|비활성/] },
|
|
195
|
+
{ label: "API or props", patterns: [/\b(api|props?|property|attribute)\b/i, /속성|프로퍼티/] },
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
"palette-from-brand": [
|
|
200
|
+
{
|
|
201
|
+
id: "palette-token-contract",
|
|
202
|
+
title: "Palette token contract",
|
|
203
|
+
required: [
|
|
204
|
+
{ label: "semantic tokens", patterns: [/\bsemantic\b.*\btoken|\b--color-[a-z0-9-]+/i, /시맨틱.*토큰|의미.*토큰/] },
|
|
205
|
+
{ label: "primitive palette", patterns: [/\bprimitive\b|\bscale\b|\bpalette\b/i, /프리미티브|팔레트/] },
|
|
206
|
+
{ label: "contrast ratios", patterns: [/\b\d+(?:\.\d+)?:1\b/] },
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
"motion-design": [
|
|
211
|
+
{
|
|
212
|
+
id: "motion-spec",
|
|
213
|
+
title: "Motion specification coverage",
|
|
214
|
+
required: [
|
|
215
|
+
{ label: "duration", patterns: [/\b\d+\s*ms\b|\bduration\b/i, /지속시간|듀레이션/] },
|
|
216
|
+
{ label: "easing", patterns: [/\beas(?:e|ing)|cubic-bezier|spring\b/i, /이징/] },
|
|
217
|
+
{ label: "reduced motion", patterns: [/\b(prefers-reduced-motion|reduced motion)\b/i, /모션 감소|움직임 감소/] },
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
illustration: [
|
|
222
|
+
{
|
|
223
|
+
id: "illustration-system",
|
|
224
|
+
title: "Illustration system coverage",
|
|
225
|
+
required: [
|
|
226
|
+
{ label: "style system", patterns: [/\b(style|visual language|system)\b/i, /스타일|시각 언어|시스템/] },
|
|
227
|
+
{ label: "usage context", patterns: [/\b(usage|use case|placement|context)\b/i, /사용처|맥락|배치/] },
|
|
228
|
+
{ label: "accessibility or alt text", patterns: [/\b(alt text|accessibility|decorative)\b/i, /대체 텍스트|접근성|장식/] },
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
print: [
|
|
233
|
+
{
|
|
234
|
+
id: "print-production",
|
|
235
|
+
title: "Print production constraints",
|
|
236
|
+
required: [
|
|
237
|
+
{ label: "CMYK", patterns: [/\bcmyk\b/i] },
|
|
238
|
+
{ label: "bleed", patterns: [/\bbleed\b/i, /도련/] },
|
|
239
|
+
{ label: "DPI or resolution", patterns: [/\b(dpi|resolution|300dpi)\b/i, /해상도/] },
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
video: [
|
|
244
|
+
{
|
|
245
|
+
id: "video-production",
|
|
246
|
+
title: "Video production constraints",
|
|
247
|
+
required: [
|
|
248
|
+
{ label: "resolution or aspect ratio", patterns: [/\b(resolution|aspect ratio|9:16|16:9|1:1)\b/i, /해상도|비율/] },
|
|
249
|
+
{ label: "framerate", patterns: [/\b(frame ?rate|fps)\b/i, /프레임/] },
|
|
250
|
+
{ label: "captions or subtitles", patterns: [/\b(caption|subtitle|srt)\b/i, /자막/] },
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
"game-ui": [
|
|
255
|
+
{
|
|
256
|
+
id: "game-ui-surface",
|
|
257
|
+
title: "Game UI surface coverage",
|
|
258
|
+
required: [
|
|
259
|
+
{ label: "HUD or menu surface", patterns: [/\b(hud|menu|inventory|store)\b/i, /HUD|메뉴|인벤토리|상점/] },
|
|
260
|
+
{ label: "platform or viewport", patterns: [/\b(platform|desktop|mobile|console|viewport)\b/i, /플랫폼|모바일|데스크톱/] },
|
|
261
|
+
{ label: "game accessibility", patterns: [/\b(accessibility|color-blind|remap|subtitle)\b/i, /접근성|색각|리맵|자막/] },
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
conversational: [
|
|
266
|
+
{
|
|
267
|
+
id: "conversation-flow",
|
|
268
|
+
title: "Conversation flow coverage",
|
|
269
|
+
required: [
|
|
270
|
+
{ label: "intents", patterns: [/\b(intent|utterance)\b/i, /의도|발화/] },
|
|
271
|
+
{ label: "fallback or error recovery", patterns: [/\b(fallback|error|repair|clarif)\w*\b/i, /폴백|오류|재질문/] },
|
|
272
|
+
{ label: "turn-taking", patterns: [/\b(turn-taking|conversation flow|dialogue)\b/i, /턴|대화 흐름/] },
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
spatial: [
|
|
277
|
+
{
|
|
278
|
+
id: "spatial-comfort",
|
|
279
|
+
title: "Spatial comfort and interaction coverage",
|
|
280
|
+
required: [
|
|
281
|
+
{ label: "comfort", patterns: [/\b(comfort|motion sickness|vestibular)\b/i, /편안함|멀미/] },
|
|
282
|
+
{ label: "depth, distance, or FOV", patterns: [/\b(depth|distance|fov|field of view)\b/i, /깊이|거리|시야각/] },
|
|
283
|
+
{ label: "input or locomotion", patterns: [/\b(input|gesture|controller|locomotion)\b/i, /입력|제스처|컨트롤러|이동/] },
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
"document-from-brief": [
|
|
288
|
+
{
|
|
289
|
+
id: "document-structure",
|
|
290
|
+
title: "Document structure coverage",
|
|
291
|
+
required: [
|
|
292
|
+
{ label: "Diataxis type", patterns: [/\b(diataxis|tutorial|how-to|reference|explanation)\b/i, /튜토리얼|하우투|레퍼런스|설명/] },
|
|
293
|
+
{ label: "audience", patterns: [/\b(audience|reader|user)\b/i, /독자|대상/] },
|
|
294
|
+
{ label: "structure", patterns: [/\b(structure|section|outline)\b/i, /구조|섹션|개요/] },
|
|
295
|
+
],
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
"slide-deck": [
|
|
299
|
+
{
|
|
300
|
+
id: "deck-story",
|
|
301
|
+
title: "Deck story coverage",
|
|
302
|
+
required: [
|
|
303
|
+
{ label: "slides", patterns: [/\bslide\b/i, /슬라이드/] },
|
|
304
|
+
{ label: "message-led title", patterns: [/\b(message|takeaway|headline|title)\b/i, /메시지|핵심|제목/] },
|
|
305
|
+
{ label: "audience or purpose", patterns: [/\b(audience|purpose|objective)\b/i, /청중|목적/] },
|
|
306
|
+
],
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
"handoff-spec": [
|
|
310
|
+
{
|
|
311
|
+
id: "handoff-implementation",
|
|
312
|
+
title: "Handoff implementation coverage",
|
|
313
|
+
required: [
|
|
314
|
+
{ label: "implementation details", patterns: [/\b(implementation|engineering|developer)\b/i, /구현|개발/] },
|
|
315
|
+
{ label: "tokens", patterns: [/\btoken/i, /토큰/] },
|
|
316
|
+
{ label: "states or specs", patterns: [/\b(state|spec|variant)\b/i, /상태|스펙|변형/] },
|
|
317
|
+
],
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
"design-system-qa": [
|
|
321
|
+
{
|
|
322
|
+
id: "qa-layers",
|
|
323
|
+
title: "Design-system QA layers",
|
|
324
|
+
required: [
|
|
325
|
+
{ label: "token or type checks", patterns: [/\b(token|type)\b/i, /토큰|타입/] },
|
|
326
|
+
{ label: "accessibility checks", patterns: [/\b(a11y|accessibility|aria)\b/i, /접근성/] },
|
|
327
|
+
{ label: "visual or regression checks", patterns: [/\b(visual|regression|snapshot|storybook)\b/i, /시각|회귀|스토리북/] },
|
|
328
|
+
],
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
"figma-token-sync": [
|
|
332
|
+
{
|
|
333
|
+
id: "figma-token-sync",
|
|
334
|
+
title: "Figma token sync coverage",
|
|
335
|
+
required: [
|
|
336
|
+
{ label: "Figma variables", patterns: [/\b(figma|variable)\b/i, /피그마|변수/] },
|
|
337
|
+
{ label: "token mapping", patterns: [/\b(token|mapping|alias)\b/i, /토큰|매핑|별칭/] },
|
|
338
|
+
{ label: "sync workflow", patterns: [/\b(sync|export|import|source of truth)\b/i, /동기화|내보내기|가져오기|원천/] },
|
|
339
|
+
],
|
|
340
|
+
},
|
|
341
|
+
],
|
|
342
|
+
"design-pr-review": [
|
|
343
|
+
{
|
|
344
|
+
id: "pr-review-evidence",
|
|
345
|
+
title: "Design PR review evidence",
|
|
346
|
+
required: [
|
|
347
|
+
{ label: "diff or changed files", patterns: [/\b(diff|changed files?|files?)\b/i, /변경 파일|diff/] },
|
|
348
|
+
{ label: "impact", patterns: [/\b(impact|risk|regression)\b/i, /영향|리스크|회귀/] },
|
|
349
|
+
{ label: "validation", patterns: [/\b(test|validation|verified|check)\b/i, /테스트|검증/] },
|
|
350
|
+
],
|
|
351
|
+
},
|
|
352
|
+
],
|
|
353
|
+
"stability-review": [
|
|
354
|
+
{
|
|
355
|
+
id: "stability-release",
|
|
356
|
+
title: "Stability review coverage",
|
|
357
|
+
required: [
|
|
358
|
+
{ label: "release or checklist", patterns: [/\b(release|checklist|launch)\b/i, /릴리스|체크리스트|출시/] },
|
|
359
|
+
{ label: "audit or tests", patterns: [/\b(audit|test|validation)\b/i, /감사|테스트|검증/] },
|
|
360
|
+
{ label: "staleness or version", patterns: [/\b(stale|version|drift|outdated)\b/i, /오래된|버전|드리프트/] },
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
function routeRequirementResult(routeId, requirement, text) {
|
|
367
|
+
const missing = requirement.required
|
|
368
|
+
.filter((item) => !hasAny(item.patterns, text))
|
|
369
|
+
.map((item) => item.label);
|
|
370
|
+
const passed = missing.length === 0;
|
|
371
|
+
|
|
372
|
+
return result({
|
|
373
|
+
id: `route-${routeId}-${requirement.id}`,
|
|
374
|
+
title: `Route: ${requirement.title}`,
|
|
375
|
+
passed,
|
|
376
|
+
severity: "warn",
|
|
377
|
+
passMessage: "Route-specific requirement is covered.",
|
|
378
|
+
failMessage: "Route-specific requirement is missing expected evidence.",
|
|
379
|
+
evidence: passed ? "" : `Missing: ${missing.join(", ")}`,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function routeRequirements(routeId) {
|
|
384
|
+
if (!routeId) return [];
|
|
385
|
+
assertKnownRouteId(routeId);
|
|
386
|
+
|
|
387
|
+
return ROUTE_REQUIREMENTS[routeId] || [];
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function summarize(results) {
|
|
391
|
+
const failures = results.filter((item) => item.level === "fail").length;
|
|
392
|
+
const warnings = results.filter((item) => item.level === "warn").length;
|
|
393
|
+
const passes = results.filter((item) => item.level === "pass").length;
|
|
394
|
+
const status = failures > 0 ? "fail" : warnings > 0 ? "warn" : "pass";
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
status,
|
|
398
|
+
passes,
|
|
399
|
+
warnings,
|
|
400
|
+
failures,
|
|
401
|
+
total: results.length,
|
|
402
|
+
score: `${passes}/${results.length}`,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export function checkArtifactContent({ content, filePath = "stdin", routeId = "" }) {
|
|
407
|
+
const text = String(content || "");
|
|
408
|
+
const trimmed = text.trim();
|
|
409
|
+
const hasColorEvidence = has(/#[0-9a-f]{3,8}\b|--color-|oklch\(|rgba?\(|hsla?\(/i, text);
|
|
410
|
+
const hasContrastRatio = has(/\b\d+(?:\.\d+)?:1\b/, text);
|
|
411
|
+
const hasGrounding = has(/\b(?:knowledge|refs)\/[A-Za-z0-9._/-]+\.md\b|PRINCIPLES\.md\b/, text);
|
|
412
|
+
const hasKeyboardFocus = has(/\b(keyboard|focus|tab order|tab key|escape|arrow key|focus-visible)\b/i, text);
|
|
413
|
+
const hasResponsive = has(/\b(responsive|mobile|desktop|tablet|breakpoint|viewport)\b/i, text);
|
|
414
|
+
const hasScreenReader = has(/\b(screen reader|assistive technolog|aria-|aria\b|sr-only|role=)\b/i, text);
|
|
415
|
+
const hasDontSection = has(/\b(don't|do not|avoid|anti-pattern|misuse)\b/i, text);
|
|
416
|
+
const hasHangul = has(/[\u3131-\uD79D]/, text);
|
|
417
|
+
const hasKoreanConsideration = has(/\b(korean|hangul|korea|kr)\b|[\u3131-\uD79D].*(한국|한글|해요체|합쇼체|본인인증|카카오|토스|네이버|명함)/i, text);
|
|
418
|
+
const hasUnresolvedMarker = has(/\b(TODO|TBD|FIXME)\b|\{\{[^}]+\}\}|<\s*(?:TODO|TBD|FIXME)[^>]*>/i, text);
|
|
419
|
+
|
|
420
|
+
const contrastPassed = hasColorEvidence ? hasContrastRatio : hasContrastRatio || has(/\bcontrast\b/i, text);
|
|
421
|
+
|
|
422
|
+
const baseResults = [
|
|
423
|
+
result({
|
|
424
|
+
id: "content-depth",
|
|
425
|
+
title: "Meaningful artifact depth",
|
|
426
|
+
passed: trimmed.length >= 200,
|
|
427
|
+
severity: "fail",
|
|
428
|
+
passMessage: "Artifact has enough content to audit.",
|
|
429
|
+
failMessage: "Artifact is too short to verify meaningfully.",
|
|
430
|
+
evidence: `${trimmed.length} characters`,
|
|
431
|
+
}),
|
|
432
|
+
result({
|
|
433
|
+
id: "unresolved-markers",
|
|
434
|
+
title: "No unresolved placeholders",
|
|
435
|
+
passed: !hasUnresolvedMarker,
|
|
436
|
+
severity: "fail",
|
|
437
|
+
passMessage: "No TODO/TBD/FIXME or template placeholders detected.",
|
|
438
|
+
failMessage: "Unresolved TODO/TBD/FIXME or template placeholder detected.",
|
|
439
|
+
}),
|
|
440
|
+
result({
|
|
441
|
+
id: "source-grounding",
|
|
442
|
+
title: "Knowledge/source grounding",
|
|
443
|
+
passed: hasGrounding,
|
|
444
|
+
severity: "warn",
|
|
445
|
+
passMessage: "Artifact cites checked knowledge or reference files.",
|
|
446
|
+
failMessage: "No knowledge/ or refs/ citation detected.",
|
|
447
|
+
}),
|
|
448
|
+
result({
|
|
449
|
+
id: "contrast",
|
|
450
|
+
title: "Explicit contrast handling",
|
|
451
|
+
passed: contrastPassed,
|
|
452
|
+
severity: hasColorEvidence ? "fail" : "warn",
|
|
453
|
+
passMessage: "Contrast handling is explicit.",
|
|
454
|
+
failMessage: hasColorEvidence
|
|
455
|
+
? "Color values or color tokens are present without an explicit contrast ratio."
|
|
456
|
+
: "No explicit contrast note or ratio detected.",
|
|
457
|
+
}),
|
|
458
|
+
result({
|
|
459
|
+
id: "keyboard-focus",
|
|
460
|
+
title: "Keyboard and focus behavior",
|
|
461
|
+
passed: hasKeyboardFocus,
|
|
462
|
+
severity: "warn",
|
|
463
|
+
passMessage: "Keyboard/focus behavior is mentioned.",
|
|
464
|
+
failMessage: "No keyboard or focus behavior note detected.",
|
|
465
|
+
}),
|
|
466
|
+
result({
|
|
467
|
+
id: "responsive",
|
|
468
|
+
title: "Responsive behavior",
|
|
469
|
+
passed: hasResponsive,
|
|
470
|
+
severity: "warn",
|
|
471
|
+
passMessage: "Responsive behavior is mentioned.",
|
|
472
|
+
failMessage: "No mobile/desktop/responsive behavior note detected.",
|
|
473
|
+
}),
|
|
474
|
+
result({
|
|
475
|
+
id: "screen-reader",
|
|
476
|
+
title: "Screen-reader semantics",
|
|
477
|
+
passed: hasScreenReader,
|
|
478
|
+
severity: "warn",
|
|
479
|
+
passMessage: "Screen-reader or ARIA behavior is mentioned.",
|
|
480
|
+
failMessage: "No screen-reader or ARIA behavior note detected.",
|
|
481
|
+
}),
|
|
482
|
+
result({
|
|
483
|
+
id: "dont-section",
|
|
484
|
+
title: "Misuse guidance",
|
|
485
|
+
passed: hasDontSection,
|
|
486
|
+
severity: "warn",
|
|
487
|
+
passMessage: "Artifact includes misuse or avoidance guidance.",
|
|
488
|
+
failMessage: "No Don't/avoid/anti-pattern guidance detected.",
|
|
489
|
+
}),
|
|
490
|
+
result({
|
|
491
|
+
id: "korean-context",
|
|
492
|
+
title: "Korean context when relevant",
|
|
493
|
+
passed: !hasHangul || hasKoreanConsideration,
|
|
494
|
+
severity: "warn",
|
|
495
|
+
passMessage: hasHangul ? "Korean-specific context is mentioned." : "No Korean text detected; rule is not applicable.",
|
|
496
|
+
failMessage: "Korean text is present without Korean-specific UX, copy, or market consideration.",
|
|
497
|
+
}),
|
|
498
|
+
];
|
|
499
|
+
const routeResults = routeRequirements(routeId).map((requirement) => routeRequirementResult(routeId, requirement, text));
|
|
500
|
+
const results = [...baseResults, ...routeResults];
|
|
501
|
+
|
|
502
|
+
return {
|
|
503
|
+
filePath,
|
|
504
|
+
...(routeId ? { routeId } : {}),
|
|
505
|
+
...summarize(results),
|
|
506
|
+
results,
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function learningCategoryForCheckResult(resultId) {
|
|
511
|
+
if (["keyboard-focus", "screen-reader"].includes(resultId)) return "accessibility";
|
|
512
|
+
if (resultId === "korean-context") return "korean";
|
|
513
|
+
return "workflow";
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function compactEvidence(evidence, maxChars = 160) {
|
|
517
|
+
const text = String(evidence || "").trim().replace(/\s+/g, " ");
|
|
518
|
+
if (!text) return "";
|
|
519
|
+
return text.length <= maxChars ? text : `${text.slice(0, maxChars - 3)}...`;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function learningTextForCheckResult(item) {
|
|
523
|
+
const evidence = compactEvidence(item.evidence);
|
|
524
|
+
const evidenceSuffix = evidence ? ` Evidence: ${evidence}` : "";
|
|
525
|
+
return `Improve future outputs by addressing ${item.title}: ${item.message}${evidenceSuffix}`;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export function buildCheckLearningCapture(report, {
|
|
529
|
+
filePath = "",
|
|
530
|
+
dryRun = true,
|
|
531
|
+
now = new Date(),
|
|
532
|
+
} = {}) {
|
|
533
|
+
const source = report.routeId ? `check:${report.routeId}` : "check:artifact";
|
|
534
|
+
const entries = (report.results || [])
|
|
535
|
+
.filter((item) => item && item.level !== "pass")
|
|
536
|
+
.map((item) => ({
|
|
537
|
+
category: learningCategoryForCheckResult(item.id),
|
|
538
|
+
text: learningTextForCheckResult(item),
|
|
539
|
+
}));
|
|
540
|
+
|
|
541
|
+
return captureLearningEntries({
|
|
542
|
+
entries,
|
|
543
|
+
source,
|
|
544
|
+
filePath: filePath || undefined,
|
|
545
|
+
dryRun,
|
|
546
|
+
now,
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
function summarizeExampleReports(reports) {
|
|
551
|
+
const failed = reports.filter((item) => item.report.status === "fail").length;
|
|
552
|
+
const warned = reports.filter((item) => item.report.status === "warn").length;
|
|
553
|
+
const passed = reports.filter((item) => item.report.status === "pass").length;
|
|
554
|
+
const status = reports.length === 0 ? "fail" : failed > 0 ? "fail" : warned > 0 ? "warn" : "pass";
|
|
555
|
+
|
|
556
|
+
return {
|
|
557
|
+
status,
|
|
558
|
+
total: reports.length,
|
|
559
|
+
passed,
|
|
560
|
+
warned,
|
|
561
|
+
failed,
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
export function checkExampleArtifacts({ designAiPath, routeId, limit = DEFAULT_EXAMPLE_LIMIT }) {
|
|
566
|
+
if (!routeId) {
|
|
567
|
+
throw new Error("--examples requires --route id");
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const discovered = listExamples({
|
|
571
|
+
designAiPath,
|
|
572
|
+
routeId,
|
|
573
|
+
limit,
|
|
574
|
+
});
|
|
575
|
+
const reports = discovered.examples.map((example) => {
|
|
576
|
+
const absolutePath = path.join(designAiPath, example.relPath);
|
|
577
|
+
const content = readFileSync(absolutePath, "utf8");
|
|
578
|
+
return {
|
|
579
|
+
example,
|
|
580
|
+
report: checkArtifactContent({
|
|
581
|
+
content,
|
|
582
|
+
filePath: absolutePath,
|
|
583
|
+
routeId,
|
|
584
|
+
}),
|
|
585
|
+
};
|
|
586
|
+
});
|
|
587
|
+
const summary = summarizeExampleReports(reports);
|
|
588
|
+
|
|
589
|
+
return {
|
|
590
|
+
mode: "examples",
|
|
591
|
+
routeId,
|
|
592
|
+
query: discovered.effectiveQuery,
|
|
593
|
+
limit,
|
|
594
|
+
status: summary.status,
|
|
595
|
+
...summary,
|
|
596
|
+
examples: reports,
|
|
597
|
+
...(reports.length === 0 ? { message: "No examples matched the selected route." } : {}),
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
function summarizeRouteReports(routes) {
|
|
602
|
+
const failedRoutes = routes.filter((item) => item.status === "fail").length;
|
|
603
|
+
const warnedRoutes = routes.filter((item) => item.status === "warn").length;
|
|
604
|
+
const passedRoutes = routes.filter((item) => item.status === "pass").length;
|
|
605
|
+
const status = failedRoutes > 0 ? "fail" : warnedRoutes > 0 ? "warn" : "pass";
|
|
606
|
+
const totalExamples = routes.reduce((sum, route) => sum + route.total, 0);
|
|
607
|
+
const failedExamples = routes.reduce((sum, route) => sum + route.failed, 0);
|
|
608
|
+
const warnedExamples = routes.reduce((sum, route) => sum + route.warned, 0);
|
|
609
|
+
const passedExamples = routes.reduce((sum, route) => sum + route.passed, 0);
|
|
610
|
+
|
|
611
|
+
return {
|
|
612
|
+
status,
|
|
613
|
+
totalRoutes: routes.length,
|
|
614
|
+
passedRoutes,
|
|
615
|
+
warnedRoutes,
|
|
616
|
+
failedRoutes,
|
|
617
|
+
totalExamples,
|
|
618
|
+
passedExamples,
|
|
619
|
+
warnedExamples,
|
|
620
|
+
failedExamples,
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export function checkAllExampleArtifacts({ designAiPath, limit = DEFAULT_EXAMPLE_LIMIT }) {
|
|
625
|
+
const routes = ROUTES.map((route) => checkExampleArtifacts({
|
|
626
|
+
designAiPath,
|
|
627
|
+
routeId: route.id,
|
|
628
|
+
limit,
|
|
629
|
+
}));
|
|
630
|
+
const summary = summarizeRouteReports(routes);
|
|
631
|
+
|
|
632
|
+
return {
|
|
633
|
+
mode: "examples-all-routes",
|
|
634
|
+
limit,
|
|
635
|
+
...summary,
|
|
636
|
+
routes,
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
export function formatCheckJson(report) {
|
|
641
|
+
return JSON.stringify(report, null, 2);
|
|
642
|
+
}
|