@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,603 @@
|
|
|
1
|
+
// Prompt generation for `design-ai prompt`.
|
|
2
|
+
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
|
|
6
|
+
import { parseBriefSourceFlag } from "./brief.mjs";
|
|
7
|
+
import { listExamples } from "./examples.mjs";
|
|
8
|
+
import { buildLearningContext, normalizeCategory, parseLearningLimit } from "./learn.mjs";
|
|
9
|
+
import { SYMLINK_PREFIX } from "./paths.mjs";
|
|
10
|
+
import { parseOutputFlags } from "./output.mjs";
|
|
11
|
+
import { readRouteManifestVersion, routeBrief, routeById } from "./route.mjs";
|
|
12
|
+
import { unknownOptionMessage } from "./suggest.mjs";
|
|
13
|
+
|
|
14
|
+
const PROMPT_OPTIONS = [
|
|
15
|
+
"-h",
|
|
16
|
+
"--help",
|
|
17
|
+
"--json",
|
|
18
|
+
"--route",
|
|
19
|
+
"--eval-template",
|
|
20
|
+
"--eval",
|
|
21
|
+
"--strict",
|
|
22
|
+
"--from-file",
|
|
23
|
+
"--stdin",
|
|
24
|
+
"--out",
|
|
25
|
+
"--force",
|
|
26
|
+
"--with-learning",
|
|
27
|
+
"--learning-category",
|
|
28
|
+
"--learning-limit",
|
|
29
|
+
];
|
|
30
|
+
const PROMPT_EVAL_VERSION = 1;
|
|
31
|
+
const PROMPT_EVAL_DEFAULT_LIMIT = 12;
|
|
32
|
+
|
|
33
|
+
export function parsePromptArgs(args) {
|
|
34
|
+
const out = {
|
|
35
|
+
briefParts: [],
|
|
36
|
+
fromFile: "",
|
|
37
|
+
stdin: false,
|
|
38
|
+
routeId: "",
|
|
39
|
+
json: false,
|
|
40
|
+
outPath: "",
|
|
41
|
+
force: false,
|
|
42
|
+
withLearning: false,
|
|
43
|
+
learningCategory: "",
|
|
44
|
+
learningLimit: 0,
|
|
45
|
+
evalTemplate: false,
|
|
46
|
+
eval: false,
|
|
47
|
+
strict: false,
|
|
48
|
+
help: false,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
52
|
+
const arg = args[i];
|
|
53
|
+
out.index = i;
|
|
54
|
+
if (arg === "-h" || arg === "--help") {
|
|
55
|
+
out.help = true;
|
|
56
|
+
} else if (arg === "--json") {
|
|
57
|
+
out.json = true;
|
|
58
|
+
} else if (arg === "--with-learning") {
|
|
59
|
+
out.withLearning = true;
|
|
60
|
+
} else if (arg === "--eval-template") {
|
|
61
|
+
out.evalTemplate = true;
|
|
62
|
+
} else if (arg === "--eval") {
|
|
63
|
+
out.eval = true;
|
|
64
|
+
} else if (arg === "--strict") {
|
|
65
|
+
out.strict = true;
|
|
66
|
+
} else if (arg === "--learning-category") {
|
|
67
|
+
const category = args[i + 1];
|
|
68
|
+
if (!category || category.startsWith("--")) throw new Error("--learning-category expects a category");
|
|
69
|
+
out.learningCategory = normalizeCategory(category);
|
|
70
|
+
i += 1;
|
|
71
|
+
} else if (arg === "--learning-limit") {
|
|
72
|
+
const limit = args[i + 1];
|
|
73
|
+
if (!limit || limit.startsWith("--")) throw new Error("--learning-limit expects an integer from 1 to 100");
|
|
74
|
+
try {
|
|
75
|
+
out.learningLimit = parseLearningLimit(limit);
|
|
76
|
+
} catch {
|
|
77
|
+
throw new Error("--learning-limit expects an integer from 1 to 100");
|
|
78
|
+
}
|
|
79
|
+
i += 1;
|
|
80
|
+
} else if (arg === "--route") {
|
|
81
|
+
const routeId = args[i + 1];
|
|
82
|
+
if (!routeId || routeId.startsWith("--")) throw new Error("--route expects a route id");
|
|
83
|
+
out.routeId = routeId;
|
|
84
|
+
i += 1;
|
|
85
|
+
} else if (parseBriefSourceFlag(args, out)) {
|
|
86
|
+
i = out.index;
|
|
87
|
+
} else if (parseOutputFlags(args, out)) {
|
|
88
|
+
i = out.index;
|
|
89
|
+
} else if (arg.startsWith("--")) {
|
|
90
|
+
throw new Error(unknownOptionMessage("prompt", arg, PROMPT_OPTIONS));
|
|
91
|
+
} else {
|
|
92
|
+
out.briefParts.push(arg);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if ((out.learningCategory || out.learningLimit) && !out.withLearning) {
|
|
97
|
+
throw new Error("--learning-category and --learning-limit require --with-learning");
|
|
98
|
+
}
|
|
99
|
+
if (out.eval && out.evalTemplate) {
|
|
100
|
+
throw new Error("Choose either --eval-template or --eval, not both");
|
|
101
|
+
}
|
|
102
|
+
if (out.strict && !out.eval) {
|
|
103
|
+
throw new Error("--strict can only be used with --eval");
|
|
104
|
+
}
|
|
105
|
+
if (out.evalTemplate && (out.briefParts.length > 0 || out.fromFile || out.stdin || out.routeId || out.withLearning)) {
|
|
106
|
+
throw new Error("--eval-template cannot be combined with a brief, --from-file, --stdin, --route, or --with-learning");
|
|
107
|
+
}
|
|
108
|
+
if (out.eval && (!out.fromFile && !out.stdin)) {
|
|
109
|
+
throw new Error("--eval requires --from-file or --stdin");
|
|
110
|
+
}
|
|
111
|
+
if (out.eval && (out.briefParts.length > 0 || out.routeId || out.withLearning)) {
|
|
112
|
+
throw new Error("--eval cannot be combined with an inline brief, --route, or --with-learning");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
...out,
|
|
117
|
+
index: undefined,
|
|
118
|
+
brief: out.briefParts.join(" ").trim(),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function slashCommandFor(commandPath, prefix = SYMLINK_PREFIX) {
|
|
123
|
+
if (!commandPath) return null;
|
|
124
|
+
const name = path.basename(commandPath, ".md");
|
|
125
|
+
return `/${prefix}${name}`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function existingPaths(entries) {
|
|
129
|
+
return entries.filter((entry) => entry.exists).map((entry) => entry.path);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function companionPlaybooks(sourceRoot, skillPaths) {
|
|
133
|
+
return skillPaths
|
|
134
|
+
.filter((skillPath) => skillPath.endsWith("/SKILL.md"))
|
|
135
|
+
.map((skillPath) => skillPath.replace(/\/SKILL\.md$/, "/PLAYBOOK.md"))
|
|
136
|
+
.filter((playbookPath) => existsSync(path.join(sourceRoot, playbookPath)));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function unique(items) {
|
|
140
|
+
return Array.from(new Set(items));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function qualityCommandForRoute(routeId, artifactPath = "output.md") {
|
|
144
|
+
return `design-ai check ${artifactPath} --route ${routeId} --strict`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const BASE_CHECKLIST = [
|
|
148
|
+
"Confirm the selected route, command, and files read before producing the artifact.",
|
|
149
|
+
"Cite checked knowledge files for material design decisions.",
|
|
150
|
+
"State assumptions and unresolved inputs explicitly.",
|
|
151
|
+
"Include accessibility notes for contrast, keyboard/focus, touch targets, and screen-reader behavior where relevant.",
|
|
152
|
+
"Include responsive behavior for mobile and desktop where relevant.",
|
|
153
|
+
"Run the route playbook verification checklist before final output.",
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
const ROUTE_CHECKLIST = {
|
|
157
|
+
"design-review": [
|
|
158
|
+
"Lead with the highest-impact issue before secondary observations.",
|
|
159
|
+
"Separate UX, visual design, and accessibility findings.",
|
|
160
|
+
"Provide concrete fixes rather than broad design advice.",
|
|
161
|
+
],
|
|
162
|
+
"website-improvement": [
|
|
163
|
+
"Include Site Profile, Audit Checklist, MCP Readiness Matrix, Refactor Plan, Prompt Generator, and Handoff Report sections.",
|
|
164
|
+
"State that implementation happens in the target website repo, not in design-ai.",
|
|
165
|
+
"Cover accessibility, responsive QA, SEO/performance, runtime issues, and verification evidence.",
|
|
166
|
+
],
|
|
167
|
+
"design-from-brief": [
|
|
168
|
+
"Produce foundations, tokens, component baseline, and handoff guidance.",
|
|
169
|
+
"Include light/dark behavior when color tokens are introduced.",
|
|
170
|
+
"Name the first 5-8 starter components for the product category.",
|
|
171
|
+
],
|
|
172
|
+
"component-spec": [
|
|
173
|
+
"Cover anatomy, variants, states, API, tokens, ARIA, keyboard behavior, and edge cases.",
|
|
174
|
+
"Cite Ant Design, MUI, and shadcn-ui references when available.",
|
|
175
|
+
"Include at least one implementation-oriented example.",
|
|
176
|
+
],
|
|
177
|
+
"palette-from-brand": [
|
|
178
|
+
"Provide semantic token names, not only hex values.",
|
|
179
|
+
"State contrast ratios for foreground/background pairs.",
|
|
180
|
+
"Separate primitive palette from semantic role tokens.",
|
|
181
|
+
],
|
|
182
|
+
"motion-design": [
|
|
183
|
+
"Specify duration, easing, choreography, trigger, and reduced-motion behavior.",
|
|
184
|
+
"Keep motion tiers aligned to micro/component/hero duration rules.",
|
|
185
|
+
],
|
|
186
|
+
"document-from-brief": [
|
|
187
|
+
"Name the Diataxis document type and keep structure consistent with it.",
|
|
188
|
+
"Lead with the answer and keep instructions active-voice.",
|
|
189
|
+
],
|
|
190
|
+
"slide-deck": [
|
|
191
|
+
"Make every slide title a message, not a topic label.",
|
|
192
|
+
"Separate speaker-led, pitch, and reading-deck assumptions.",
|
|
193
|
+
],
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
function checklistForRoute(route) {
|
|
197
|
+
return unique([
|
|
198
|
+
...BASE_CHECKLIST,
|
|
199
|
+
...(ROUTE_CHECKLIST[route.id] || []),
|
|
200
|
+
]);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function buildPromptPlan({
|
|
204
|
+
brief,
|
|
205
|
+
sourceRoot,
|
|
206
|
+
prefix = SYMLINK_PREFIX,
|
|
207
|
+
routeId = "",
|
|
208
|
+
withLearning = false,
|
|
209
|
+
learningFilePath = "",
|
|
210
|
+
learningCategory = "",
|
|
211
|
+
learningLimit = 0,
|
|
212
|
+
}) {
|
|
213
|
+
const route = routeId
|
|
214
|
+
? routeById({ routeId, sourceRoot })
|
|
215
|
+
: routeBrief({ brief, sourceRoot, limit: 1 })[0] || null;
|
|
216
|
+
if (!route) return null;
|
|
217
|
+
|
|
218
|
+
const slashCommand = route.command ? slashCommandFor(route.command.path, prefix) : null;
|
|
219
|
+
const skillPaths = existingPaths(route.skills);
|
|
220
|
+
const referenceExamples = listExamples({
|
|
221
|
+
designAiPath: sourceRoot,
|
|
222
|
+
query: brief,
|
|
223
|
+
routeId: route.id,
|
|
224
|
+
limit: 2,
|
|
225
|
+
}).examples;
|
|
226
|
+
const filesToRead = unique([
|
|
227
|
+
"AGENTS.md",
|
|
228
|
+
...(route.command?.exists ? [route.command.path] : []),
|
|
229
|
+
...skillPaths,
|
|
230
|
+
...companionPlaybooks(sourceRoot, skillPaths),
|
|
231
|
+
...existingPaths(route.agents),
|
|
232
|
+
...existingPaths(route.knowledge),
|
|
233
|
+
...referenceExamples.map((example) => example.relPath),
|
|
234
|
+
]);
|
|
235
|
+
|
|
236
|
+
const checklist = checklistForRoute(route);
|
|
237
|
+
const qualityCommand = qualityCommandForRoute(route.id);
|
|
238
|
+
const learningContext = withLearning
|
|
239
|
+
? buildLearningContext({
|
|
240
|
+
filePath: learningFilePath || undefined,
|
|
241
|
+
category: learningCategory,
|
|
242
|
+
limit: learningLimit || 12,
|
|
243
|
+
query: brief,
|
|
244
|
+
})
|
|
245
|
+
: null;
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
brief,
|
|
249
|
+
version: readRouteManifestVersion(sourceRoot),
|
|
250
|
+
route,
|
|
251
|
+
slashCommand,
|
|
252
|
+
referenceExamples,
|
|
253
|
+
filesToRead,
|
|
254
|
+
checklist,
|
|
255
|
+
qualityCommand,
|
|
256
|
+
...(learningContext ? { learningContext } : {}),
|
|
257
|
+
prompt: renderPrompt({
|
|
258
|
+
brief,
|
|
259
|
+
route,
|
|
260
|
+
slashCommand,
|
|
261
|
+
referenceExamples,
|
|
262
|
+
filesToRead,
|
|
263
|
+
checklist,
|
|
264
|
+
qualityCommand,
|
|
265
|
+
learningContext,
|
|
266
|
+
}),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function formatPromptJson(plan) {
|
|
271
|
+
return JSON.stringify(plan, null, 2);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function isoTimestamp(now = new Date()) {
|
|
275
|
+
return (now instanceof Date ? now : new Date(now)).toISOString();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function buildPromptEvalTemplate({ sourceRoot, generatedAt = new Date() } = {}) {
|
|
279
|
+
return {
|
|
280
|
+
version: PROMPT_EVAL_VERSION,
|
|
281
|
+
generatedAt: isoTimestamp(generatedAt),
|
|
282
|
+
sourcePromptVersion: sourceRoot ? readRouteManifestVersion(sourceRoot) : "unknown",
|
|
283
|
+
description: "Deterministic prompt-plan checkpoints for design-ai agent workflows.",
|
|
284
|
+
cases: [
|
|
285
|
+
{
|
|
286
|
+
id: "component-spec-prompt-plan",
|
|
287
|
+
brief: "Spec a Button component API with variants, states, props, and keyboard accessibility",
|
|
288
|
+
expectedRouteId: "component-spec",
|
|
289
|
+
requiredFiles: [
|
|
290
|
+
"AGENTS.md",
|
|
291
|
+
"commands/component-spec.md",
|
|
292
|
+
"skills/component-spec-writer/SKILL.md",
|
|
293
|
+
"skills/component-spec-writer/PLAYBOOK.md",
|
|
294
|
+
"knowledge/PRINCIPLES.md",
|
|
295
|
+
"knowledge/a11y/keyboard-and-focus.md",
|
|
296
|
+
],
|
|
297
|
+
requiredChecklist: [
|
|
298
|
+
"Cover anatomy, variants, states, API, tokens, ARIA, keyboard behavior, and edge cases.",
|
|
299
|
+
"Include at least one implementation-oriented example.",
|
|
300
|
+
],
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
id: "website-improvement-prompt-plan",
|
|
304
|
+
brief: "Improve a SaaS homepage with website audit, SEO, performance, MCP readiness, refactor plan, and handoff report",
|
|
305
|
+
expectedRouteId: "website-improvement",
|
|
306
|
+
requiredFiles: [
|
|
307
|
+
"AGENTS.md",
|
|
308
|
+
"commands/website-improvement.md",
|
|
309
|
+
"skills/website-improvement/SKILL.md",
|
|
310
|
+
"skills/website-improvement/PLAYBOOK.md",
|
|
311
|
+
"docs/WEBSITE-IMPROVEMENT.md",
|
|
312
|
+
],
|
|
313
|
+
requiredChecklist: [
|
|
314
|
+
"Include Site Profile, Audit Checklist, MCP Readiness Matrix, Refactor Plan, Prompt Generator, and Handoff Report sections.",
|
|
315
|
+
"State that implementation happens in the target website repo, not in design-ai.",
|
|
316
|
+
],
|
|
317
|
+
},
|
|
318
|
+
],
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function promptEvalStatus(counts) {
|
|
323
|
+
if (counts.fail > 0) return "fail";
|
|
324
|
+
if (counts.warn > 0) return "warn";
|
|
325
|
+
return "pass";
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function normalizePromptEvalPayload(evalText, source = "prompt-eval.json") {
|
|
329
|
+
let payload;
|
|
330
|
+
try {
|
|
331
|
+
payload = JSON.parse(evalText);
|
|
332
|
+
} catch (err) {
|
|
333
|
+
throw new Error(`Could not parse prompt eval JSON from ${source}: ${err.message}`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
337
|
+
throw new Error("Prompt eval payload must be a JSON object");
|
|
338
|
+
}
|
|
339
|
+
if (payload.version !== PROMPT_EVAL_VERSION) {
|
|
340
|
+
throw new Error(`Prompt eval payload version must be ${PROMPT_EVAL_VERSION}`);
|
|
341
|
+
}
|
|
342
|
+
if (!Array.isArray(payload.cases)) {
|
|
343
|
+
throw new Error("Prompt eval payload must include a cases array");
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return payload;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function normalizeStringList(rawValue, label, id) {
|
|
350
|
+
if (rawValue === undefined || rawValue === null) return [];
|
|
351
|
+
if (!Array.isArray(rawValue)) {
|
|
352
|
+
throw new Error(`Prompt eval case ${id} ${label} must be an array`);
|
|
353
|
+
}
|
|
354
|
+
return rawValue.map((item) => String(item || "").trim()).filter(Boolean);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function normalizePromptEvalCase(rawCase, index) {
|
|
358
|
+
if (!rawCase || typeof rawCase !== "object" || Array.isArray(rawCase)) {
|
|
359
|
+
throw new Error(`Prompt eval case ${index + 1} must be a JSON object`);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const id = String(rawCase.id || `case-${index + 1}`).trim();
|
|
363
|
+
const brief = String(rawCase.brief || "").trim();
|
|
364
|
+
const expectedRouteId = String(rawCase.expectedRouteId || rawCase.expected || "").trim();
|
|
365
|
+
const routeId = String(rawCase.routeId || "").trim();
|
|
366
|
+
const learningCategory = String(rawCase.learningCategory || "").trim();
|
|
367
|
+
const learningLimit = rawCase.learningLimit === undefined || rawCase.learningLimit === null
|
|
368
|
+
? 0
|
|
369
|
+
: Number(rawCase.learningLimit);
|
|
370
|
+
|
|
371
|
+
if (!id) throw new Error(`Prompt eval case ${index + 1} is missing id`);
|
|
372
|
+
if (!brief) throw new Error(`Prompt eval case ${id} is missing brief`);
|
|
373
|
+
if (!expectedRouteId) throw new Error(`Prompt eval case ${id} is missing expectedRouteId`);
|
|
374
|
+
if (learningLimit && (!Number.isInteger(learningLimit) || learningLimit < 1 || learningLimit > 100)) {
|
|
375
|
+
throw new Error(`Prompt eval case ${id} learningLimit must be an integer from 1 to 100`);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return {
|
|
379
|
+
id,
|
|
380
|
+
brief,
|
|
381
|
+
expectedRouteId,
|
|
382
|
+
routeId,
|
|
383
|
+
requiredFiles: normalizeStringList(rawCase.requiredFiles, "requiredFiles", id),
|
|
384
|
+
requiredChecklist: normalizeStringList(rawCase.requiredChecklist, "requiredChecklist", id),
|
|
385
|
+
requiredPromptFragments: normalizeStringList(rawCase.requiredPromptFragments, "requiredPromptFragments", id),
|
|
386
|
+
withLearning: Boolean(rawCase.withLearning),
|
|
387
|
+
requireLearningContext: Boolean(rawCase.requireLearningContext),
|
|
388
|
+
learningCategory,
|
|
389
|
+
learningLimit,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function includesEveryText(haystackItems, requiredItems) {
|
|
394
|
+
return requiredItems.filter((required) => !haystackItems.some((item) => item.includes(required)));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function evaluatePromptPlanCase(testCase, {
|
|
398
|
+
sourceRoot,
|
|
399
|
+
prefix = SYMLINK_PREFIX,
|
|
400
|
+
learningFilePath = "",
|
|
401
|
+
}) {
|
|
402
|
+
const plan = buildPromptPlan({
|
|
403
|
+
brief: testCase.brief,
|
|
404
|
+
sourceRoot,
|
|
405
|
+
prefix,
|
|
406
|
+
routeId: testCase.routeId,
|
|
407
|
+
withLearning: testCase.withLearning || testCase.requireLearningContext,
|
|
408
|
+
learningFilePath,
|
|
409
|
+
learningCategory: testCase.learningCategory,
|
|
410
|
+
learningLimit: testCase.learningLimit,
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
const issues = [];
|
|
414
|
+
const warnings = [];
|
|
415
|
+
const routeId = plan?.route?.id || "";
|
|
416
|
+
if (!plan) {
|
|
417
|
+
issues.push("No prompt plan was produced.");
|
|
418
|
+
} else if (routeId !== testCase.expectedRouteId) {
|
|
419
|
+
issues.push(`Expected route ${testCase.expectedRouteId}, but prompt plan selected ${routeId}.`);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const missingRequiredFiles = plan
|
|
423
|
+
? testCase.requiredFiles.filter((file) => !plan.filesToRead.includes(file))
|
|
424
|
+
: testCase.requiredFiles;
|
|
425
|
+
if (missingRequiredFiles.length > 0) {
|
|
426
|
+
issues.push(`Missing required files: ${missingRequiredFiles.join(", ")}`);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const missingChecklist = plan
|
|
430
|
+
? includesEveryText(plan.checklist, testCase.requiredChecklist)
|
|
431
|
+
: testCase.requiredChecklist;
|
|
432
|
+
if (missingChecklist.length > 0) {
|
|
433
|
+
issues.push(`Missing checklist items: ${missingChecklist.join(" | ")}`);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const missingPromptFragments = plan
|
|
437
|
+
? testCase.requiredPromptFragments.filter((fragment) => !plan.prompt.includes(fragment))
|
|
438
|
+
: testCase.requiredPromptFragments;
|
|
439
|
+
if (missingPromptFragments.length > 0) {
|
|
440
|
+
issues.push(`Missing prompt fragments: ${missingPromptFragments.join(" | ")}`);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const learningContext = plan?.learningContext || null;
|
|
444
|
+
if (testCase.requireLearningContext && !learningContext) {
|
|
445
|
+
issues.push("Expected learning context, but none was included.");
|
|
446
|
+
} else if (testCase.withLearning && learningContext && learningContext.entries.length === 0) {
|
|
447
|
+
warnings.push("Learning context was requested but selected no entries.");
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const status = issues.length > 0 ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
451
|
+
|
|
452
|
+
return {
|
|
453
|
+
id: testCase.id,
|
|
454
|
+
status,
|
|
455
|
+
message: issues[0] || warnings[0] || "Prompt plan matched expectations.",
|
|
456
|
+
expectedRouteId: testCase.expectedRouteId,
|
|
457
|
+
routeId,
|
|
458
|
+
forcedRouteId: testCase.routeId,
|
|
459
|
+
filesToReadCount: plan?.filesToRead?.length || 0,
|
|
460
|
+
requiredFiles: testCase.requiredFiles,
|
|
461
|
+
missingRequiredFiles,
|
|
462
|
+
requiredChecklist: testCase.requiredChecklist,
|
|
463
|
+
missingChecklist,
|
|
464
|
+
requiredPromptFragments: testCase.requiredPromptFragments,
|
|
465
|
+
missingPromptFragments,
|
|
466
|
+
learningContext: learningContext
|
|
467
|
+
? {
|
|
468
|
+
category: learningContext.category,
|
|
469
|
+
limit: learningContext.limit,
|
|
470
|
+
count: learningContext.entries.length,
|
|
471
|
+
selectedCount: learningContext.selection?.selectedCount || 0,
|
|
472
|
+
}
|
|
473
|
+
: null,
|
|
474
|
+
issues,
|
|
475
|
+
warnings,
|
|
476
|
+
brief: testCase.brief,
|
|
477
|
+
plan,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
export function promptEvalReport({
|
|
482
|
+
evalText,
|
|
483
|
+
source = "prompt-eval.json",
|
|
484
|
+
sourceRoot,
|
|
485
|
+
prefix = SYMLINK_PREFIX,
|
|
486
|
+
learningFilePath = "",
|
|
487
|
+
generatedAt = new Date(),
|
|
488
|
+
}) {
|
|
489
|
+
const payload = normalizePromptEvalPayload(evalText, source);
|
|
490
|
+
const normalizedCases = payload.cases.map((testCase, index) => normalizePromptEvalCase(testCase, index));
|
|
491
|
+
const cases = normalizedCases.map((testCase) => evaluatePromptPlanCase(testCase, {
|
|
492
|
+
sourceRoot,
|
|
493
|
+
prefix,
|
|
494
|
+
learningFilePath,
|
|
495
|
+
}));
|
|
496
|
+
const counts = cases.reduce(
|
|
497
|
+
(acc, testCase) => ({
|
|
498
|
+
...acc,
|
|
499
|
+
[testCase.status]: acc[testCase.status] + 1,
|
|
500
|
+
}),
|
|
501
|
+
{ pass: 0, warn: 0, fail: 0 },
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
return {
|
|
505
|
+
version: readRouteManifestVersion(sourceRoot),
|
|
506
|
+
evalVersion: payload.version,
|
|
507
|
+
source,
|
|
508
|
+
generatedAt: isoTimestamp(generatedAt),
|
|
509
|
+
status: promptEvalStatus(counts),
|
|
510
|
+
summary: {
|
|
511
|
+
total: cases.length,
|
|
512
|
+
pass: counts.pass,
|
|
513
|
+
warn: counts.warn,
|
|
514
|
+
fail: counts.fail,
|
|
515
|
+
},
|
|
516
|
+
cases,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export function renderPrompt({
|
|
521
|
+
brief,
|
|
522
|
+
route,
|
|
523
|
+
slashCommand,
|
|
524
|
+
referenceExamples = [],
|
|
525
|
+
filesToRead,
|
|
526
|
+
checklist = checklistForRoute(route),
|
|
527
|
+
qualityCommand = qualityCommandForRoute(route.id),
|
|
528
|
+
learningContext = null,
|
|
529
|
+
}) {
|
|
530
|
+
const lines = [];
|
|
531
|
+
lines.push("# design-ai task prompt");
|
|
532
|
+
lines.push("");
|
|
533
|
+
lines.push(`Task: ${brief}`);
|
|
534
|
+
lines.push("");
|
|
535
|
+
const routeDetail = route.forced ? "forced" : `${route.confidence} confidence`;
|
|
536
|
+
lines.push(`${route.forced ? "Selected route" : "Recommended route"}: ${route.label} (${routeDetail})`);
|
|
537
|
+
lines.push(`Route id: ${route.id}`);
|
|
538
|
+
if (route.explanation?.summary) {
|
|
539
|
+
lines.push(`Routing reason: ${route.explanation.summary}`);
|
|
540
|
+
}
|
|
541
|
+
if (route.matchedKeywords.length > 0) {
|
|
542
|
+
lines.push(`Matched keywords: ${route.matchedKeywords.join(", ")}`);
|
|
543
|
+
} else if (route.forced) {
|
|
544
|
+
lines.push("Matched keywords: route selected via --route");
|
|
545
|
+
} else if (route.fallback) {
|
|
546
|
+
lines.push("Matched keywords: fallback route");
|
|
547
|
+
}
|
|
548
|
+
lines.push("");
|
|
549
|
+
|
|
550
|
+
if (slashCommand) {
|
|
551
|
+
lines.push("Preferred command:");
|
|
552
|
+
lines.push("");
|
|
553
|
+
lines.push("```text");
|
|
554
|
+
lines.push(`${slashCommand} ${brief}`);
|
|
555
|
+
lines.push("```");
|
|
556
|
+
lines.push("");
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (referenceExamples.length > 0) {
|
|
560
|
+
lines.push("Reference examples:");
|
|
561
|
+
for (const example of referenceExamples) {
|
|
562
|
+
lines.push(`- ${example.relPath} — ${example.title}`);
|
|
563
|
+
}
|
|
564
|
+
lines.push("");
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (learningContext) {
|
|
568
|
+
lines.push("Learned design context:");
|
|
569
|
+
lines.push("");
|
|
570
|
+
lines.push(learningContext.markdown);
|
|
571
|
+
lines.push("");
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
lines.push("Before producing the artifact, read these files in order:");
|
|
575
|
+
for (const file of filesToRead) {
|
|
576
|
+
lines.push(`- ${file}`);
|
|
577
|
+
}
|
|
578
|
+
lines.push("");
|
|
579
|
+
|
|
580
|
+
lines.push("Execution rules:");
|
|
581
|
+
lines.push("- Follow AGENTS.md and knowledge/PRINCIPLES.md first.");
|
|
582
|
+
lines.push("- Use the listed command or skill playbook as the workflow source of truth.");
|
|
583
|
+
lines.push("- Cite checked knowledge files when making design recommendations.");
|
|
584
|
+
lines.push("- Include accessibility notes: contrast, keyboard/focus, touch target, and screen-reader behavior where relevant.");
|
|
585
|
+
lines.push("- Save the final Markdown artifact as output.md when practical, then run the suggested artifact QA command.");
|
|
586
|
+
lines.push("- Run the playbook verification checklist before final output.");
|
|
587
|
+
lines.push("- If required inputs are missing, ask one concise clarifying question; otherwise proceed.");
|
|
588
|
+
lines.push("");
|
|
589
|
+
|
|
590
|
+
lines.push("Suggested artifact QA command:");
|
|
591
|
+
lines.push("");
|
|
592
|
+
lines.push("```bash");
|
|
593
|
+
lines.push(qualityCommand);
|
|
594
|
+
lines.push("```");
|
|
595
|
+
lines.push("");
|
|
596
|
+
|
|
597
|
+
lines.push("Verification checklist:");
|
|
598
|
+
for (const item of checklist) {
|
|
599
|
+
lines.push(`- [ ] ${item}`);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return lines.join("\n");
|
|
603
|
+
}
|