better-design 0.34.0 → 0.35.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/dist/index.js +42 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1403,7 +1403,7 @@ Better Design provides design systems, design principles and UI review checks fo
|
|
|
1403
1403
|
"find-design-system": "Searches Better Design's catalog of design systems by industry, personality or a description of the interface, and returns ranked matches with a preview link for each. Use it when the user wants a design system or a visual direction for an app, site, page, dashboard or presentation.",
|
|
1404
1404
|
"get-design-system-kit": "Returns the build kit for a catalog design system or a generated project. `target` picks the format: `react` returns one shadcn install command for every component and the tokens, `html` returns framework-free token and component CSS for inline canvases, `react-native` and `swiftui` return mobile kits, `shopify` returns Liquid theme files, `dtcg` returns a W3C Design Tokens document, and `store-screenshots` returns slide files and a render script for App Store and Google Play screenshots. `component` narrows the React install to one component.",
|
|
1405
1405
|
"get-inspiration": 'Returns real reference designs from Better Design\'s library as images. `type` picks the collection: today `app-store-screenshots`, the App Store screenshot sets of shipped apps, each with its title and category. `category`, such as "Productivity", narrows the sets, and `limit` sets how many come back, 1 to 6.',
|
|
1406
|
-
"create-design-system": "Starts generating a custom design system from a description of the product and its look, and returns the project id and project URL at once. Generation runs in the background and typically takes 1 to 3 minutes. get-design-system-status reports progress and returns the install command when it finishes. `baseDesignSystemId` starts from a catalog system, and `brandCss` builds from an existing brand token sheet, such as the output of extract-design-system. Each call uses one credit from the user's Better Design account. Anyone with the registry or preview URL can view the generated source and previews.",
|
|
1406
|
+
"create-design-system": "Starts generating a custom design system from a description of the product and its look, and returns the project id and project URL at once. Generation runs in the background and typically takes 1 to 3 minutes. get-design-system-status reports progress and returns the install command when it finishes. `baseDesignSystemId` starts from a catalog system the user picked, `userConfirmedCustom` records that the user chose fully custom, and `brandCss` builds from an existing brand token sheet, such as the output of extract-design-system. With none of the three, it generates nothing and returns the top catalog matches to show the user. Each call uses one credit from the user's Better Design account. Anyone with the registry or preview URL can view the generated source and previews.",
|
|
1407
1407
|
"get-design-system-status": "Reports the progress of a design system started with create-design-system. While generation runs it returns the current stage. When generation finishes it returns the live preview URL and the `npx shadcn add` install command.",
|
|
1408
1408
|
"preview-design-system": "Returns a visual preview of a catalog design system: its palette, typography, buttons, card, input and badge, with a link to the full live showcase. Takes an id from find-design-system.",
|
|
1409
1409
|
"get-design-config": "Returns the design config saved on a generated project: exact color tokens, radius, fonts and icon library, including values the user tuned on the project page.",
|
|
@@ -13966,6 +13966,32 @@ Examples:
|
|
|
13966
13966
|
- "fintech startup" \u2192 Stripe design system
|
|
13967
13967
|
- "playful education app" \u2192 Duolingo design system
|
|
13968
13968
|
- "minimal developer tools" \u2192 Linear design system`;
|
|
13969
|
+
const formatCatalogMatches = (results) => results.map(
|
|
13970
|
+
(r) => [
|
|
13971
|
+
// Markdown link so the NAME is clickable in the host (Claude Code,
|
|
13972
|
+
// ChatGPT, claude.ai all render markdown links). Keep it intact when
|
|
13973
|
+
// presenting so the user can open the preview in one click.
|
|
13974
|
+
`### [${r.title}](${APP_BASE_URL}/design-systems/${r.id})`,
|
|
13975
|
+
r.description,
|
|
13976
|
+
`_${r.personality.join(", ")}_ \xB7 id: \`${r.id}\``
|
|
13977
|
+
].join("\n")
|
|
13978
|
+
).join("\n\n");
|
|
13979
|
+
const askForBaseChoice = async (prompt) => {
|
|
13980
|
+
const heading = "# Choose a starting point first\n\nNothing was generated.";
|
|
13981
|
+
try {
|
|
13982
|
+
const results = await provider.searchDesignSystems(prompt, 4);
|
|
13983
|
+
if (results.length === 0) {
|
|
13984
|
+
return `${heading} No catalog system matched this prompt. Ask the user whether to go fully custom, then call create-design-system again with \`userConfirmedCustom: true\`.`;
|
|
13985
|
+
}
|
|
13986
|
+
return `${heading} Show the user these options, keeping each name as its clickable link, and ask which to start from or whether to go fully custom. Then call create-design-system again with the chosen \`id\` as \`baseDesignSystemId\`, or with \`userConfirmedCustom: true\` if the user chose fully custom. Do not pick for the user.
|
|
13987
|
+
|
|
13988
|
+
---
|
|
13989
|
+
|
|
13990
|
+
${formatCatalogMatches(results)}`;
|
|
13991
|
+
} catch {
|
|
13992
|
+
return `${heading} The catalog search failed, so call \`find-design-system\` with the app description, show the user the top matches, and ask which to start from or whether to go fully custom.`;
|
|
13993
|
+
}
|
|
13994
|
+
};
|
|
13969
13995
|
const makeSearchHandler = (toolName, includeBuildRules = false) => async ({ query }) => {
|
|
13970
13996
|
const start = Date.now();
|
|
13971
13997
|
const finish = (response, topResults, isError = false, errorMessage) => {
|
|
@@ -13993,27 +14019,20 @@ ${includeBuildRules ? BUILD_TARGET_RULE : DESIGN_TRADEOFF_RULE}`
|
|
|
13993
14019
|
topResults
|
|
13994
14020
|
);
|
|
13995
14021
|
}
|
|
13996
|
-
const
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
// ChatGPT, claude.ai all render markdown links). Keep it intact when
|
|
14000
|
-
// presenting so the user can open the preview in one click.
|
|
14001
|
-
`### [${r.title}](${APP_BASE_URL}/design-systems/${r.id})`,
|
|
14002
|
-
`${r.description}`,
|
|
14003
|
-
`_${r.personality.join(", ")}_ \xB7 id: \`${r.id}\``
|
|
14004
|
-
].join("\n")
|
|
14005
|
-
).join("\n\n");
|
|
14022
|
+
const productPagePointer = COMMERCIAL_QUERY.test(query) ? `
|
|
14023
|
+
|
|
14024
|
+
${PRODUCT_PAGE_POINTER}` : "";
|
|
14006
14025
|
return finish(
|
|
14007
14026
|
{
|
|
14008
14027
|
content: [{
|
|
14009
14028
|
type: "text",
|
|
14010
14029
|
text: `# Catalog matches
|
|
14011
14030
|
|
|
14012
|
-
Keep any already selected design system and its assigned icons; do not reopen that choice unless requested. If none is selected, present these as options, keeping each name as its clickable markdown link (no scores) so they can open the preview. Explain each option's expected buyer fit and trade-offs using known project context; do not claim conversion effects without evidence. Recommend by buyer, never by the product's material or subject (a steel tool does not need a steel-dark UI). For ecommerce and DTC product pages, default to light, warm, photography-led systems unless the brand already owns a dark identity. Ask which to start their brand from, or to go fully custom, then pass the chosen \`id\` as \`baseDesignSystemId\` to create-design-system
|
|
14031
|
+
Keep any already selected design system and its assigned icons; do not reopen that choice unless requested. If none is selected, present these as options, keeping each name as its clickable markdown link (no scores) so they can open the preview. Explain each option's expected buyer fit and trade-offs using known project context; do not claim conversion effects without evidence. Recommend by buyer, never by the product's material or subject (a steel tool does not need a steel-dark UI). For ecommerce and DTC product pages, default to light, warm, photography-led systems unless the brand already owns a dark identity. Ask which to start their brand from, or to go fully custom, then pass the chosen \`id\` as \`baseDesignSystemId\` to create-design-system, or pass \`userConfirmedCustom: true\` if they choose fully custom.${productPagePointer}
|
|
14013
14032
|
|
|
14014
14033
|
---
|
|
14015
14034
|
|
|
14016
|
-
${
|
|
14035
|
+
${formatCatalogMatches(results)}
|
|
14017
14036
|
|
|
14018
14037
|
---
|
|
14019
14038
|
|
|
@@ -14705,7 +14724,7 @@ _${installNote}_`,
|
|
|
14705
14724
|
|
|
14706
14725
|
${DESIGN_TRADEOFF_RULE}
|
|
14707
14726
|
|
|
14708
|
-
**Use this for a new custom brand, even when the user never mentions design or branding** (a design system IS the app's brand). Keep an already selected system and its assigned icons unless the user requests a different direction; a redesign alone does not require regenerating the brand. When no system is selected, first call \`find-design-system\` with the app description, show the user the top ~4 matches, and ask which to start from (passed here as \`baseDesignSystemId\`) or whether to go fully custom. Then derive the \`prompt\` from the app (name, domain, vibe), generate, show it with \`get-design-system-status\`, and build with that brand. Also use it when the user explicitly wants a **custom** design system instead of installing an existing one via \`get-design-system-kit\`.
|
|
14727
|
+
**Use this for a new custom brand, even when the user never mentions design or branding** (a design system IS the app's brand). Keep an already selected system and its assigned icons unless the user requests a different direction; a redesign alone does not require regenerating the brand. When no system is selected, first call \`find-design-system\` with the app description, show the user the top ~4 matches, and ask which to start from (passed here as \`baseDesignSystemId\`) or whether to go fully custom (passed here as \`userConfirmedCustom: true\`). A call with neither, and no \`brandCss\`, generates nothing: it returns those matches for you to show the user. Then derive the \`prompt\` from the app (name, domain, vibe), generate, show it with \`get-design-system-status\`, and build with that brand. Also use it when the user explicitly wants a **custom** design system instead of installing an existing one via \`get-design-system-kit\`.
|
|
14709
14728
|
|
|
14710
14729
|
**When the user has an existing brand** (their site, Figma file, or stylesheet): run \`extract-design-system\` or \`extract-from-url\` first and pass the resulting token sheet (the fenced \`\`\`css block, verbatim: the \`:root { ... }\` and optional \`.dark { ... }\` blocks) as \`brandCss\`. The generation is then pinned to that brand: no catalog aesthetic is retrieved, the sheet's colors, fonts and radii override everything, and later design-system switches are refused. Copy the block exactly; do not retype or trim it.
|
|
14711
14730
|
|
|
@@ -14718,6 +14737,7 @@ Share the project URL with the user right away so they can watch the generation
|
|
|
14718
14737
|
inputSchema: z14.object({
|
|
14719
14738
|
prompt: z14.string().min(1).max(1e4).describe("Describe the design system the user wants. E.g. 'A warm, minimal design system for a personal finance app, soft pastels, rounded corners' or 'A brutalist developer tool aesthetic with sharp edges and monospace type'."),
|
|
14720
14739
|
baseDesignSystemId: z14.string().optional().describe("Optional. The catalog id the USER picked from the `find-design-system` matches you showed them, used to bias generation toward that aesthetic (e.g. a theme tweak on top of Linear). Leave empty only when the user chose fully custom."),
|
|
14740
|
+
userConfirmedCustom: z14.boolean().optional().describe("Set true only when the user saw the find-design-system matches and chose fully custom. Without it, baseDesignSystemId or brandCss, the tool returns the matches and generates nothing."),
|
|
14721
14741
|
brandCss: z14.string().max(5e4).optional().describe("Optional. The user's extracted brand token sheet, verbatim: the fenced css block from extract-design-system / extract-from-url (`:root { --background: ...; }` plus optional `.dark { ... }`). When set, generation builds FROM this brand instead of a catalog look-alike, and baseDesignSystemId is ignored (a catalog base would leak its identity past the brand tokens).")
|
|
14722
14742
|
}),
|
|
14723
14743
|
// Each call starts a new generation and returns a new project id, so it
|
|
@@ -14731,7 +14751,10 @@ Share the project URL with the user right away so they can watch the generation
|
|
|
14731
14751
|
openWorldHint: true
|
|
14732
14752
|
}
|
|
14733
14753
|
},
|
|
14734
|
-
async ({ prompt, baseDesignSystemId, brandCss }) => tracked("create-design-system", { query: prompt, hasBase: Boolean(baseDesignSystemId), hasBrand: Boolean(brandCss) }, async () => {
|
|
14754
|
+
async ({ prompt, baseDesignSystemId, brandCss, userConfirmedCustom }) => tracked("create-design-system", { query: prompt, hasBase: Boolean(baseDesignSystemId), hasBrand: Boolean(brandCss), userConfirmedCustom: Boolean(userConfirmedCustom) }, async () => {
|
|
14755
|
+
if (!baseDesignSystemId && !brandCss && !userConfirmedCustom) {
|
|
14756
|
+
return { content: [{ type: "text", text: await askForBaseChoice(prompt) }] };
|
|
14757
|
+
}
|
|
14735
14758
|
const startUrl = `${APP_BASE_URL}/api/projects/anonymous`;
|
|
14736
14759
|
let projectId;
|
|
14737
14760
|
const requestHeaders = { "Content-Type": "application/json" };
|
|
@@ -14971,7 +14994,7 @@ Check again in ~30 seconds. Watch it live on the project page: ${projectUrl}` }]
|
|
|
14971
14994
|
})
|
|
14972
14995
|
);
|
|
14973
14996
|
}
|
|
14974
|
-
var SHADCN_INIT_IF_MISSING, SAFE_COMPONENT_NAME_RE, DS_INDEX_SCHEMA;
|
|
14997
|
+
var SHADCN_INIT_IF_MISSING, SAFE_COMPONENT_NAME_RE, DS_INDEX_SCHEMA, COMMERCIAL_QUERY, PRODUCT_PAGE_POINTER;
|
|
14975
14998
|
var init_design_system_tools = __esm({
|
|
14976
14999
|
"../shared/src/mcp/tools/design-system-tools.ts"() {
|
|
14977
15000
|
"use strict";
|
|
@@ -14995,6 +15018,8 @@ var init_design_system_tools = __esm({
|
|
|
14995
15018
|
DS_INDEX_SCHEMA = z14.object({
|
|
14996
15019
|
baseComponents: z14.array(z14.object({ name: z14.string() })).optional()
|
|
14997
15020
|
});
|
|
15021
|
+
COMMERCIAL_QUERY = /\b(product pages?|pdp|shops?|(?<!app )stores?|storefront|e-?commerce|webshop|dtc|d2c|shopify|checkout|buy box)\b|[$€£]\s?\d/i;
|
|
15022
|
+
PRODUCT_PAGE_POINTER = 'This looks like a product page or a store. Before you build, call `get-ui-principle({ topic: "product-pages" })` for section order by buyer objection, the squint test and buyer-matched tone. For a catalog or checkout, also call `get-ux-principle` with topic `commerce-catalog` or `commerce-checkout`.';
|
|
14998
15023
|
}
|
|
14999
15024
|
});
|
|
15000
15025
|
|
|
@@ -29561,7 +29586,7 @@ var MCP_IMPLEMENTATION_VERSION;
|
|
|
29561
29586
|
var init_version2 = __esm({
|
|
29562
29587
|
"../shared/src/mcp/version.ts"() {
|
|
29563
29588
|
"use strict";
|
|
29564
|
-
MCP_IMPLEMENTATION_VERSION = "0.
|
|
29589
|
+
MCP_IMPLEMENTATION_VERSION = "0.35.0";
|
|
29565
29590
|
}
|
|
29566
29591
|
});
|
|
29567
29592
|
|