better-design 0.41.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +113 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ the variables in every mode, the text and effect styles, and the components
|
|
|
45
45
|
with their variant options. It writes them to one JSON file. You confirm the
|
|
46
46
|
read in the plugin panel. Pass that file to `create-figma-prototype` as
|
|
47
47
|
`kitPath` in model mode, and the prototype uses the kit's colours, font and
|
|
48
|
-
radius.
|
|
48
|
+
radius. Pass a `projectId` to also keep the kit on that project.
|
|
49
49
|
|
|
50
50
|
A frame from a file that was not built from a Better Design library has no
|
|
51
51
|
components to map, so pass `mode: "model"` and a catalog `system`. The plugin
|
package/dist/index.js
CHANGED
|
@@ -12856,7 +12856,7 @@ var init_agent_feedback = __esm({
|
|
|
12856
12856
|
|
|
12857
12857
|
// ../shared/src/schema.ts
|
|
12858
12858
|
import { z as z8 } from "zod";
|
|
12859
|
-
var vector2, messageRoleEnum, messageTypeEnum, designSystemStatusEnum, onboardingPathValues, onboardingPathSchema, onboardingPathSqlValues, mcpIssueCategoryValues, mcpIssueStatusValues, mcpIssueImprovementStatusValues, mcpIssueImprovementVerdictValues, mcpIssueImprovementStatusSchema, mcpIssueImprovementVerdictSchema, mcpIssueImprovementStatusSqlValues, mcpIssueImprovementVerdictSqlValues, designConfigSchema, projectMemoryDataSchema, projects, messages, projectMemory, fragments, usage, scrapeBlock, resourceAccess, user, signupAlertDeliveries, billingAlertDeliveries, billingEmailDeliveries, TEAM_RULES_MAX_BYTES, teamRules, TEAM_RULE_PROPOSAL_MAX_BYTES, teamRuleProposals, projectRuleKindValues, PROJECT_RULE_MAX_BYTES, PROJECT_RULE_NAME_MAX_CHARS, projectRules, agentFeedbackStatusValues, agentFeedback, billingSubscription, githubInstallationClaim, githubInstallation, featureAccess, session, account, verification, jwks, oauthClient, oauthRefreshToken, oauthAccessToken, oauthConsent, designSystems, designSystemComponents, foundationalDocs, apiKeys, claimCodes, emailCampaignSends, emailCampaignSteps, projectEvents, adminProjectReadRouteValues, adminProjectReads, iconLibraries, dsSearchQueries, mcpToolCalls, mcpClientConnections, evalVerdicts, generationInputs, mcpIssues, mcpIssueImprovements, productOutcomeMetricValues, productOutcomeStatusValues, productOutcomeBlockedReasonValues, mcpIssueImprovementOutcomes, projectsRelations, projectMemoryRelations, mcpIssuesRelations, mcpIssueImprovementsRelations, messagesRelations, fragmentsRelations, designSystemsRelations, designSystemComponentsRelations, insertProjectSchema, selectProjectSchema, insertMessageSchema, selectMessageSchema, insertFragmentSchema, selectFragmentSchema, insertProjectMemorySchema, selectProjectMemorySchema, insertDesignSystemSchema, selectDesignSystemSchema, insertDesignSystemComponentSchema, selectDesignSystemComponentSchema, insertFoundationalDocSchema, selectFoundationalDocSchema, insertIconLibrarySchema, selectIconLibrarySchema, insertApiKeySchema, selectApiKeySchema, insertUserSchema, selectUserSchema, insertSignupAlertDeliverySchema, selectSignupAlertDeliverySchema, insertEmailCampaignSendSchema, selectEmailCampaignSendSchema, insertEmailCampaignStepSchema, selectEmailCampaignStepSchema, insertMcpIssueImprovementSchema, selectMcpIssueImprovementSchema, pluginAuthNonces;
|
|
12859
|
+
var vector2, messageRoleEnum, messageTypeEnum, designSystemStatusEnum, onboardingPathValues, onboardingPathSchema, onboardingPathSqlValues, mcpIssueCategoryValues, mcpIssueStatusValues, mcpIssueImprovementStatusValues, mcpIssueImprovementVerdictValues, mcpIssueImprovementStatusSchema, mcpIssueImprovementVerdictSchema, mcpIssueImprovementStatusSqlValues, mcpIssueImprovementVerdictSqlValues, designConfigSchema, projectMemoryDataSchema, projects, messages, projectMemory, fragments, usage, scrapeBlock, resourceAccess, user, signupAlertDeliveries, billingAlertDeliveries, billingEmailDeliveries, TEAM_RULES_MAX_BYTES, teamRules, TEAM_RULE_PROPOSAL_MAX_BYTES, teamRuleProposals, projectRuleKindValues, PROJECT_RULE_MAX_BYTES, PROJECT_RULE_NAME_MAX_CHARS, projectRules, projectFigmaKits, agentFeedbackStatusValues, agentFeedback, billingSubscription, githubInstallationClaim, githubInstallation, featureAccess, session, account, verification, jwks, oauthClient, oauthRefreshToken, oauthAccessToken, oauthConsent, designSystems, designSystemComponents, foundationalDocs, apiKeys, claimCodes, emailCampaignSends, emailCampaignSteps, projectEvents, adminProjectReadRouteValues, adminProjectReads, iconLibraries, dsSearchQueries, mcpToolCalls, mcpClientConnections, evalVerdicts, generationInputs, mcpIssues, mcpIssueImprovements, productOutcomeMetricValues, productOutcomeStatusValues, productOutcomeBlockedReasonValues, mcpIssueImprovementOutcomes, projectsRelations, projectMemoryRelations, mcpIssuesRelations, mcpIssueImprovementsRelations, messagesRelations, fragmentsRelations, designSystemsRelations, designSystemComponentsRelations, insertProjectSchema, selectProjectSchema, insertMessageSchema, selectMessageSchema, insertFragmentSchema, selectFragmentSchema, insertProjectMemorySchema, selectProjectMemorySchema, insertDesignSystemSchema, selectDesignSystemSchema, insertDesignSystemComponentSchema, selectDesignSystemComponentSchema, insertFoundationalDocSchema, selectFoundationalDocSchema, insertIconLibrarySchema, selectIconLibrarySchema, insertApiKeySchema, selectApiKeySchema, insertUserSchema, selectUserSchema, insertSignupAlertDeliverySchema, selectSignupAlertDeliverySchema, insertEmailCampaignSendSchema, selectEmailCampaignSendSchema, insertEmailCampaignStepSchema, selectEmailCampaignStepSchema, insertMcpIssueImprovementSchema, selectMcpIssueImprovementSchema, pluginAuthNonces, accountPages;
|
|
12860
12860
|
var init_schema2 = __esm({
|
|
12861
12861
|
"../shared/src/schema.ts"() {
|
|
12862
12862
|
"use strict";
|
|
@@ -13308,6 +13308,13 @@ var init_schema2 = __esm({
|
|
|
13308
13308
|
)
|
|
13309
13309
|
]
|
|
13310
13310
|
);
|
|
13311
|
+
projectFigmaKits = pgTable("project_figma_kits", {
|
|
13312
|
+
projectId: uuid("project_id").primaryKey().references(() => projects.id, { onDelete: "cascade" }),
|
|
13313
|
+
/** The Figma file name the kit came from. */
|
|
13314
|
+
file: text("file").notNull(),
|
|
13315
|
+
kit: jsonb("kit").$type().notNull(),
|
|
13316
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
|
|
13317
|
+
});
|
|
13311
13318
|
agentFeedbackStatusValues = [
|
|
13312
13319
|
"open",
|
|
13313
13320
|
"accepted",
|
|
@@ -14229,6 +14236,25 @@ var init_schema2 = __esm({
|
|
|
14229
14236
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
14230
14237
|
expiresAt: timestamp("expires_at").notNull()
|
|
14231
14238
|
});
|
|
14239
|
+
accountPages = pgTable(
|
|
14240
|
+
"account_pages",
|
|
14241
|
+
{
|
|
14242
|
+
id: text("id").primaryKey(),
|
|
14243
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
14244
|
+
designSystemId: text("design_system_id").notNull(),
|
|
14245
|
+
website: text("website").notNull(),
|
|
14246
|
+
company: text("company").notNull(),
|
|
14247
|
+
headline: text("headline").notNull(),
|
|
14248
|
+
problem: text("problem"),
|
|
14249
|
+
offer: text("offer").notNull(),
|
|
14250
|
+
/** Up to three short proof points: results, customers or numbers. [BD-1093] */
|
|
14251
|
+
proofs: text("proofs").array(),
|
|
14252
|
+
ctaLabel: text("cta_label").notNull(),
|
|
14253
|
+
ctaUrl: text("cta_url").notNull(),
|
|
14254
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull()
|
|
14255
|
+
},
|
|
14256
|
+
(t) => [index("account_pages_user_id_idx").on(t.userId)]
|
|
14257
|
+
);
|
|
14232
14258
|
}
|
|
14233
14259
|
});
|
|
14234
14260
|
|
|
@@ -30644,7 +30670,7 @@ var MCP_IMPLEMENTATION_VERSION;
|
|
|
30644
30670
|
var init_version2 = __esm({
|
|
30645
30671
|
"../shared/src/mcp/version.ts"() {
|
|
30646
30672
|
"use strict";
|
|
30647
|
-
MCP_IMPLEMENTATION_VERSION = "0.
|
|
30673
|
+
MCP_IMPLEMENTATION_VERSION = "0.42.0";
|
|
30648
30674
|
}
|
|
30649
30675
|
});
|
|
30650
30676
|
|
|
@@ -30792,6 +30818,7 @@ __export(api_client_exports, {
|
|
|
30792
30818
|
listPrinciples: () => listPrinciples,
|
|
30793
30819
|
proposeTeamRule: () => proposeTeamRule,
|
|
30794
30820
|
readInspiration: () => readInspiration,
|
|
30821
|
+
saveProjectFigmaKit: () => saveProjectFigmaKit,
|
|
30795
30822
|
saveProjectRule: () => saveProjectRule,
|
|
30796
30823
|
saveTeamRules: () => saveTeamRules,
|
|
30797
30824
|
searchDesignSystems: () => searchDesignSystems,
|
|
@@ -30965,6 +30992,9 @@ async function saveProjectRule(projectId, save, replaceExisting) {
|
|
|
30965
30992
|
throw error;
|
|
30966
30993
|
}
|
|
30967
30994
|
}
|
|
30995
|
+
async function saveProjectFigmaKit(projectId, kit) {
|
|
30996
|
+
return request(`/v1/project-kit/${encodeURIComponent(projectId)}`, { method: "PUT", body: kit });
|
|
30997
|
+
}
|
|
30968
30998
|
function postAlert(body) {
|
|
30969
30999
|
return fetch(`${API_URL2}/api/internal/alert`, {
|
|
30970
31000
|
method: "POST",
|
|
@@ -31577,7 +31607,7 @@ var init_code_rules = __esm({
|
|
|
31577
31607
|
|
|
31578
31608
|
// ../shared/src/lint/length-rules.ts
|
|
31579
31609
|
function pxMatches(value) {
|
|
31580
|
-
const unquoted = value.replace(QUOTED_RE, (
|
|
31610
|
+
const unquoted = value.replace(QUOTED_RE, (quoted3) => " ".repeat(quoted3.length));
|
|
31581
31611
|
return [...unquoted.matchAll(PX_RE)].filter((match) => Number.parseFloat(match[0]) !== 0);
|
|
31582
31612
|
}
|
|
31583
31613
|
function pxValues(value) {
|
|
@@ -34739,6 +34769,16 @@ review-ui-code({ files: [{ path: "components/signup-form.tsx", content: "..." },
|
|
|
34739
34769
|
|
|
34740
34770
|
// ../shared/src/mcp/figma-kit.ts
|
|
34741
34771
|
import { z as z36 } from "zod";
|
|
34772
|
+
function kitCounts(kit) {
|
|
34773
|
+
return {
|
|
34774
|
+
file: kit.file,
|
|
34775
|
+
collections: kit.collections.length,
|
|
34776
|
+
variables: kit.collections.reduce((total, collection) => total + collection.variables.length, 0),
|
|
34777
|
+
textStyles: kit.textStyles.length,
|
|
34778
|
+
effectStyles: kit.effectStyles.length,
|
|
34779
|
+
components: kit.components.length
|
|
34780
|
+
};
|
|
34781
|
+
}
|
|
34742
34782
|
var colorSchema, kitValueSchema, kitVariableSchema, kitCollectionSchema, kitTextStyleSchema, kitEffectStyleSchema, kitComponentSchema, figmaKitSchema;
|
|
34743
34783
|
var init_figma_kit = __esm({
|
|
34744
34784
|
"../shared/src/mcp/figma-kit.ts"() {
|
|
@@ -35837,6 +35877,38 @@ var init_figma_model_providers = __esm({
|
|
|
35837
35877
|
}
|
|
35838
35878
|
});
|
|
35839
35879
|
|
|
35880
|
+
// ../shared/src/mcp/figma-kit-gaps.ts
|
|
35881
|
+
function describeKitGaps(gaps) {
|
|
35882
|
+
if (gaps.length === 0) return "An agent can use every component set in this kit.";
|
|
35883
|
+
const names = (reason) => {
|
|
35884
|
+
const all = gaps.filter((gap) => gap.reason === reason).map((gap) => quoted2(gap.component));
|
|
35885
|
+
const shown = all.slice(0, NAMES_SHOWN).join(", ");
|
|
35886
|
+
return { count: all.length, list: all.length > NAMES_SHOWN ? `${shown} and ${all.length - NAMES_SHOWN} more` : shown };
|
|
35887
|
+
};
|
|
35888
|
+
const crowded = names("many-variant-properties");
|
|
35889
|
+
const missing = names("no-match-in-code");
|
|
35890
|
+
const renamed = names("name-differs-from-code");
|
|
35891
|
+
const unruled = names("no-use-rule");
|
|
35892
|
+
return [
|
|
35893
|
+
"Before an agent builds with this kit:",
|
|
35894
|
+
crowded.count ? `- ${crowded.count} set(s) have more than ${VARIANT_PROPERTY_LIMIT} variant properties, so an agent may pick the wrong variant: ${crowded.list}.` : "",
|
|
35895
|
+
missing.count ? `- ${missing.count} set(s) have no part in code, so an agent builds them from plain layers: ${missing.list}.` : "",
|
|
35896
|
+
renamed.count ? `- ${renamed.count} set(s) build as a part with another name, so check each one: ${renamed.list}.` : "",
|
|
35897
|
+
unruled.count ? `- ${unruled.count} set(s) have no use rule, so an agent does not know when to use them: ${unruled.list}. Save one with set-team-rules, kind "use".` : ""
|
|
35898
|
+
].filter(Boolean).join("\n");
|
|
35899
|
+
}
|
|
35900
|
+
var VARIANT_PROPERTY_LIMIT, NAME_MAX_CHARS, quoted2, NAMES_SHOWN;
|
|
35901
|
+
var init_figma_kit_gaps = __esm({
|
|
35902
|
+
"../shared/src/mcp/figma-kit-gaps.ts"() {
|
|
35903
|
+
"use strict";
|
|
35904
|
+
init_project_rules();
|
|
35905
|
+
VARIANT_PROPERTY_LIMIT = 3;
|
|
35906
|
+
NAME_MAX_CHARS = 80;
|
|
35907
|
+
quoted2 = (name) => JSON.stringify(name.replace(/\s+/g, " ").trim().slice(0, NAME_MAX_CHARS));
|
|
35908
|
+
NAMES_SHOWN = 8;
|
|
35909
|
+
}
|
|
35910
|
+
});
|
|
35911
|
+
|
|
35840
35912
|
// ../shared/src/mcp/figma-relay.ts
|
|
35841
35913
|
import { z as z40 } from "zod";
|
|
35842
35914
|
function noPluginMessage() {
|
|
@@ -36281,7 +36353,7 @@ ${page.html}` }],
|
|
|
36281
36353
|
}
|
|
36282
36354
|
);
|
|
36283
36355
|
}
|
|
36284
|
-
function registerFigmaKitTool(server) {
|
|
36356
|
+
function registerFigmaKitTool(server, saveKit) {
|
|
36285
36357
|
server.registerTool(
|
|
36286
36358
|
"read-figma-kit",
|
|
36287
36359
|
{
|
|
@@ -36291,10 +36363,12 @@ function registerFigmaKitTool(server) {
|
|
|
36291
36363
|
"the text and effect styles, and every component with the options of its variant properties.",
|
|
36292
36364
|
"Writes them as one JSON file and returns the counts. The Better Design plugin must be open in",
|
|
36293
36365
|
"that file, and the designer confirms the read in the plugin panel. Only the file's own items are",
|
|
36294
|
-
"read; a library the file uses is read from its own file."
|
|
36366
|
+
"read; a library the file uses is read from its own file. Pass a projectId to also keep the kit on",
|
|
36367
|
+
"that Better Design project, so later calls build with the client's own names and values."
|
|
36295
36368
|
].join(" "),
|
|
36296
36369
|
inputSchema: z41.object({
|
|
36297
|
-
outputPath: z41.string().describe("Where to write the kit JSON. Relative paths resolve against the working directory.")
|
|
36370
|
+
outputPath: z41.string().describe("Where to write the kit JSON. Relative paths resolve against the working directory."),
|
|
36371
|
+
projectId: z41.guid().optional().describe("A Better Design project id. The kit is kept on it, replacing the one it held.")
|
|
36298
36372
|
}),
|
|
36299
36373
|
outputSchema: z41.object({
|
|
36300
36374
|
status: z41.enum(["completed", "failed"]),
|
|
@@ -36305,11 +36379,21 @@ function registerFigmaKitTool(server) {
|
|
|
36305
36379
|
variables: z41.number().optional(),
|
|
36306
36380
|
textStyles: z41.number().optional(),
|
|
36307
36381
|
effectStyles: z41.number().optional(),
|
|
36308
|
-
components: z41.number().optional()
|
|
36382
|
+
components: z41.number().optional(),
|
|
36383
|
+
projectId: z41.string().optional(),
|
|
36384
|
+
gaps: z41.array(
|
|
36385
|
+
z41.object({
|
|
36386
|
+
component: z41.string(),
|
|
36387
|
+
page: z41.string(),
|
|
36388
|
+
reason: z41.enum(["many-variant-properties", "no-use-rule", "no-match-in-code", "name-differs-from-code"]),
|
|
36389
|
+
detail: z41.string()
|
|
36390
|
+
})
|
|
36391
|
+
).optional(),
|
|
36392
|
+
nameMap: z41.array(z41.object({ component: z41.string(), part: z41.string().nullable(), match: z41.enum(["same", "family", "none"]) })).optional()
|
|
36309
36393
|
}),
|
|
36310
36394
|
annotations: { readOnlyHint: false, openWorldHint: true }
|
|
36311
36395
|
},
|
|
36312
|
-
async ({ outputPath }) => {
|
|
36396
|
+
async ({ outputPath, projectId }) => {
|
|
36313
36397
|
const failed = (message2) => ({
|
|
36314
36398
|
content: [{ type: "text", text: message2 }],
|
|
36315
36399
|
structuredContent: { status: "failed", message: message2 },
|
|
@@ -36319,6 +36403,7 @@ function registerFigmaKitTool(server) {
|
|
|
36319
36403
|
if (!started) {
|
|
36320
36404
|
return failed("Another Better Design session already owns the Figma relay port. Close it and try again.");
|
|
36321
36405
|
}
|
|
36406
|
+
if (projectId && !saveKit) return failed("This server cannot reach a Better Design project. Run the stdio server with an API key.");
|
|
36322
36407
|
if (!await waitForPlugin(started)) return failed(noPluginMessage());
|
|
36323
36408
|
const { answer } = started.queue.ask(void 0, void 0, "kit");
|
|
36324
36409
|
const result = await answer;
|
|
@@ -36329,17 +36414,23 @@ function registerFigmaKitTool(server) {
|
|
|
36329
36414
|
await mkdir2(dirname4(path9), { recursive: true });
|
|
36330
36415
|
await writeFile2(path9, `${JSON.stringify(kit, null, 2)}
|
|
36331
36416
|
`, "utf8");
|
|
36332
|
-
const counts =
|
|
36333
|
-
|
|
36334
|
-
|
|
36335
|
-
|
|
36336
|
-
|
|
36337
|
-
|
|
36338
|
-
|
|
36339
|
-
|
|
36417
|
+
const { file, ...counts } = kitCounts(kit);
|
|
36418
|
+
let message = `${file}: ${counts.components} component(s), ${counts.variables} variable(s) in ${counts.collections} collection(s), ${counts.textStyles} text style(s) and ${counts.effectStyles} effect style(s). Written to ${path9}.`;
|
|
36419
|
+
let gaps;
|
|
36420
|
+
let nameMap;
|
|
36421
|
+
if (projectId && saveKit) {
|
|
36422
|
+
try {
|
|
36423
|
+
({ gaps, nameMap } = await saveKit(projectId, kit));
|
|
36424
|
+
message = `${describeKitGaps(gaps)}
|
|
36425
|
+
|
|
36426
|
+
${message} Kept on project ${projectId}.`;
|
|
36427
|
+
} catch (error) {
|
|
36428
|
+
return failed(`${message} The kit was not kept on project ${projectId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
36429
|
+
}
|
|
36430
|
+
}
|
|
36340
36431
|
return {
|
|
36341
36432
|
content: [{ type: "text", text: message }],
|
|
36342
|
-
structuredContent: { status: "completed", message, path: path9, file
|
|
36433
|
+
structuredContent: { status: "completed", message, path: path9, file, ...counts, projectId, gaps, nameMap }
|
|
36343
36434
|
};
|
|
36344
36435
|
}
|
|
36345
36436
|
);
|
|
@@ -36353,6 +36444,8 @@ var init_figma_prototype_tool = __esm({
|
|
|
36353
36444
|
init_figma_model();
|
|
36354
36445
|
init_figma_model_handoff();
|
|
36355
36446
|
init_figma_model_providers();
|
|
36447
|
+
init_figma_kit();
|
|
36448
|
+
init_figma_kit_gaps();
|
|
36356
36449
|
init_figma_relay();
|
|
36357
36450
|
init_figma_relay_server();
|
|
36358
36451
|
relay = null;
|
|
@@ -36469,7 +36562,8 @@ async function startServer() {
|
|
|
36469
36562
|
sendAgentFeedback: sendAgentFeedback2,
|
|
36470
36563
|
confirmAgentClaim: confirmAgentClaim2,
|
|
36471
36564
|
trackToolUsage: trackToolUsage2,
|
|
36472
|
-
trackMcpInstalled: trackMcpInstalled2
|
|
36565
|
+
trackMcpInstalled: trackMcpInstalled2,
|
|
36566
|
+
saveProjectFigmaKit: saveProjectFigmaKit2
|
|
36473
36567
|
} = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
36474
36568
|
const { isFirstConnect: isFirstConnect2 } = await Promise.resolve().then(() => (init_install_marker(), install_marker_exports));
|
|
36475
36569
|
const { mcpDebugLog: mcpDebugLog2 } = await Promise.resolve().then(() => (init_mcp_debug_log(), mcp_debug_log_exports));
|
|
@@ -36500,7 +36594,7 @@ async function startServer() {
|
|
|
36500
36594
|
});
|
|
36501
36595
|
registerReviewTool2(server, onToolUsage);
|
|
36502
36596
|
registerFigmaPrototypeTool2(server);
|
|
36503
|
-
registerFigmaKitTool2(server);
|
|
36597
|
+
registerFigmaKitTool2(server, saveProjectFigmaKit2);
|
|
36504
36598
|
server.server.oninitialized = () => {
|
|
36505
36599
|
try {
|
|
36506
36600
|
const info = server.server.getClientVersion?.();
|