webstudio 0.274.4 → 0.274.5
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/lib/{cli-DFVUpwsS.js → cli-CVetloSj.js} +722 -289
- package/lib/cli.js +1 -1
- package/lib/{framework-react-router-C6Ra_yxB.js → framework-react-router-D_ph8aB5.js} +2 -2
- package/lib/{framework-remix-B0x9qavm.js → framework-remix-DPrszLh-.js} +2 -2
- package/lib/{framework-vike-ssg-CPpMMlL7.js → framework-vike-ssg-BvV5cdbB.js} +2 -2
- package/lib/{metas-CS7NxloQ.js → metas-CwMKOOmR.js} +1 -1
- package/package.json +20 -15
- package/templates/cloudflare/package.json +1 -1
- package/templates/defaults/package.json +8 -8
- package/templates/react-router/package.json +8 -8
- package/templates/react-router-cloudflare/package.json +1 -1
- package/templates/ssg/package.json +6 -6
|
@@ -5205,7 +5205,7 @@ const publicApiOperationDocumentation = [
|
|
|
5205
5205
|
description: "Update page settings and metadata",
|
|
5206
5206
|
requiredOptions: ["page", "json"],
|
|
5207
5207
|
examples: [
|
|
5208
|
-
'webstudio update-page --page page-id --title Pricing --description "Pricing plans" --json'
|
|
5208
|
+
'webstudio update-page --page page-id --title "\\"Pricing\\"" --description "\\"Pricing plans\\"" --json'
|
|
5209
5209
|
]
|
|
5210
5210
|
},
|
|
5211
5211
|
{
|
|
@@ -5378,7 +5378,7 @@ const publicApiOperationDocumentation = [
|
|
|
5378
5378
|
},
|
|
5379
5379
|
{
|
|
5380
5380
|
command: "update-props",
|
|
5381
|
-
description: "Create or update element
|
|
5381
|
+
description: "Create or update direct element prop values; use this for fixed strings, numbers, booleans, JSON, assets, pages, parameters, and resources. Editor tokens are limited to content-mode props",
|
|
5382
5382
|
requiredOptions: ["input", "json"],
|
|
5383
5383
|
examples: ["webstudio update-props --input props.json --json"]
|
|
5384
5384
|
},
|
|
@@ -5390,7 +5390,7 @@ const publicApiOperationDocumentation = [
|
|
|
5390
5390
|
},
|
|
5391
5391
|
{
|
|
5392
5392
|
command: "bind-props",
|
|
5393
|
-
description: "Bind element props to expressions, parameters, resources, or actions",
|
|
5393
|
+
description: "Bind element props to dynamic expressions, parameters, resources, or actions. Do not use for fixed string values; use update-props instead",
|
|
5394
5394
|
requiredOptions: ["input", "json"],
|
|
5395
5395
|
examples: ["webstudio bind-props --input bindings.json --json"]
|
|
5396
5396
|
},
|
|
@@ -6123,6 +6123,7 @@ const withDefaultPermit = (operation) => {
|
|
|
6123
6123
|
permit: operation.permit ?? (operation.method === "query" ? "view" : "build"),
|
|
6124
6124
|
description: documentation.description,
|
|
6125
6125
|
inputFields: inputFieldsLookup[operation.command] ?? [],
|
|
6126
|
+
inputFieldTypes: operation.inputFieldTypes ?? {},
|
|
6126
6127
|
requiredOptions: documentation.requiredOptions,
|
|
6127
6128
|
examples: documentation.examples,
|
|
6128
6129
|
localCapable: runtimeOperation2 !== void 0,
|
|
@@ -6352,14 +6353,16 @@ const publicApiOperationInputs = [
|
|
|
6352
6353
|
id: "instances.append",
|
|
6353
6354
|
method: "mutation",
|
|
6354
6355
|
path: "api.instances.append",
|
|
6355
|
-
client: "appendInstance"
|
|
6356
|
+
client: "appendInstance",
|
|
6357
|
+
inputFieldTypes: { children: "array" }
|
|
6356
6358
|
},
|
|
6357
6359
|
{
|
|
6358
6360
|
command: "move-instance",
|
|
6359
6361
|
id: "instances.move",
|
|
6360
6362
|
method: "mutation",
|
|
6361
6363
|
path: "api.instances.move",
|
|
6362
|
-
client: "moveInstance"
|
|
6364
|
+
client: "moveInstance",
|
|
6365
|
+
inputFieldTypes: { moves: "array" }
|
|
6363
6366
|
},
|
|
6364
6367
|
{
|
|
6365
6368
|
command: "clone-instance",
|
|
@@ -6373,7 +6376,8 @@ const publicApiOperationInputs = [
|
|
|
6373
6376
|
id: "instances.delete",
|
|
6374
6377
|
method: "mutation",
|
|
6375
6378
|
path: "api.instances.delete",
|
|
6376
|
-
client: "deleteInstance"
|
|
6379
|
+
client: "deleteInstance",
|
|
6380
|
+
inputFieldTypes: { instanceIds: "array" }
|
|
6377
6381
|
},
|
|
6378
6382
|
{
|
|
6379
6383
|
command: "update-props",
|
|
@@ -6381,7 +6385,8 @@ const publicApiOperationInputs = [
|
|
|
6381
6385
|
method: "mutation",
|
|
6382
6386
|
path: "api.instances.updateProps",
|
|
6383
6387
|
client: "updateProps",
|
|
6384
|
-
permit: "edit"
|
|
6388
|
+
permit: "edit",
|
|
6389
|
+
inputFieldTypes: { updates: "array" }
|
|
6385
6390
|
},
|
|
6386
6391
|
{
|
|
6387
6392
|
command: "delete-props",
|
|
@@ -6389,14 +6394,16 @@ const publicApiOperationInputs = [
|
|
|
6389
6394
|
method: "mutation",
|
|
6390
6395
|
path: "api.instances.deleteProps",
|
|
6391
6396
|
client: "deleteProps",
|
|
6392
|
-
permit: "edit"
|
|
6397
|
+
permit: "edit",
|
|
6398
|
+
inputFieldTypes: { deletions: "array" }
|
|
6393
6399
|
},
|
|
6394
6400
|
{
|
|
6395
6401
|
command: "bind-props",
|
|
6396
6402
|
id: "instances.bindProps",
|
|
6397
6403
|
method: "mutation",
|
|
6398
6404
|
path: "api.instances.bindProps",
|
|
6399
|
-
client: "bindProps"
|
|
6405
|
+
client: "bindProps",
|
|
6406
|
+
inputFieldTypes: { bindings: "array" }
|
|
6400
6407
|
},
|
|
6401
6408
|
{
|
|
6402
6409
|
command: "list-texts",
|
|
@@ -6425,14 +6432,16 @@ const publicApiOperationInputs = [
|
|
|
6425
6432
|
id: "styles.updateDeclarations",
|
|
6426
6433
|
method: "mutation",
|
|
6427
6434
|
path: "api.styles.updateDeclarations",
|
|
6428
|
-
client: "updateStyleDeclarations"
|
|
6435
|
+
client: "updateStyleDeclarations",
|
|
6436
|
+
inputFieldTypes: { updates: "array" }
|
|
6429
6437
|
},
|
|
6430
6438
|
{
|
|
6431
6439
|
command: "delete-styles",
|
|
6432
6440
|
id: "styles.deleteDeclarations",
|
|
6433
6441
|
method: "mutation",
|
|
6434
6442
|
path: "api.styles.deleteDeclarations",
|
|
6435
|
-
client: "deleteStyleDeclarations"
|
|
6443
|
+
client: "deleteStyleDeclarations",
|
|
6444
|
+
inputFieldTypes: { deletions: "array" }
|
|
6436
6445
|
},
|
|
6437
6446
|
{
|
|
6438
6447
|
command: "replace-styles",
|
|
@@ -6453,42 +6462,48 @@ const publicApiOperationInputs = [
|
|
|
6453
6462
|
id: "designTokens.create",
|
|
6454
6463
|
method: "mutation",
|
|
6455
6464
|
path: "api.designTokens.create",
|
|
6456
|
-
client: "createDesignTokens"
|
|
6465
|
+
client: "createDesignTokens",
|
|
6466
|
+
inputFieldTypes: { tokens: "array" }
|
|
6457
6467
|
},
|
|
6458
6468
|
{
|
|
6459
6469
|
command: "update-design-token-styles",
|
|
6460
6470
|
id: "designTokens.updateStyles",
|
|
6461
6471
|
method: "mutation",
|
|
6462
6472
|
path: "api.designTokens.updateStyles",
|
|
6463
|
-
client: "updateDesignTokenStyles"
|
|
6473
|
+
client: "updateDesignTokenStyles",
|
|
6474
|
+
inputFieldTypes: { updates: "array" }
|
|
6464
6475
|
},
|
|
6465
6476
|
{
|
|
6466
6477
|
command: "delete-design-token-styles",
|
|
6467
6478
|
id: "designTokens.deleteStyles",
|
|
6468
6479
|
method: "mutation",
|
|
6469
6480
|
path: "api.designTokens.deleteStyles",
|
|
6470
|
-
client: "deleteDesignTokenStyles"
|
|
6481
|
+
client: "deleteDesignTokenStyles",
|
|
6482
|
+
inputFieldTypes: { deletions: "array" }
|
|
6471
6483
|
},
|
|
6472
6484
|
{
|
|
6473
6485
|
command: "attach-design-token",
|
|
6474
6486
|
id: "designTokens.attach",
|
|
6475
6487
|
method: "mutation",
|
|
6476
6488
|
path: "api.designTokens.attach",
|
|
6477
|
-
client: "attachDesignToken"
|
|
6489
|
+
client: "attachDesignToken",
|
|
6490
|
+
inputFieldTypes: { instanceIds: "array" }
|
|
6478
6491
|
},
|
|
6479
6492
|
{
|
|
6480
6493
|
command: "detach-design-token",
|
|
6481
6494
|
id: "designTokens.detach",
|
|
6482
6495
|
method: "mutation",
|
|
6483
6496
|
path: "api.designTokens.detach",
|
|
6484
|
-
client: "detachDesignToken"
|
|
6497
|
+
client: "detachDesignToken",
|
|
6498
|
+
inputFieldTypes: { instanceIds: "array" }
|
|
6485
6499
|
},
|
|
6486
6500
|
{
|
|
6487
6501
|
command: "extract-design-token",
|
|
6488
6502
|
id: "designTokens.extract",
|
|
6489
6503
|
method: "mutation",
|
|
6490
6504
|
path: "api.designTokens.extract",
|
|
6491
|
-
client: "extractDesignToken"
|
|
6505
|
+
client: "extractDesignToken",
|
|
6506
|
+
inputFieldTypes: { instanceIds: "array", removeLocalProps: "array" }
|
|
6492
6507
|
},
|
|
6493
6508
|
{
|
|
6494
6509
|
command: "list-css-variables",
|
|
@@ -6509,7 +6524,8 @@ const publicApiOperationInputs = [
|
|
|
6509
6524
|
id: "cssVariables.delete",
|
|
6510
6525
|
method: "mutation",
|
|
6511
6526
|
path: "api.cssVariables.delete",
|
|
6512
|
-
client: "deleteCssVariables"
|
|
6527
|
+
client: "deleteCssVariables",
|
|
6528
|
+
inputFieldTypes: { names: "array" }
|
|
6513
6529
|
},
|
|
6514
6530
|
{
|
|
6515
6531
|
command: "rewrite-css-variable-refs",
|
|
@@ -6683,7 +6699,8 @@ const publicApiOperationInputs = [
|
|
|
6683
6699
|
id: "assets.delete",
|
|
6684
6700
|
method: "mutation",
|
|
6685
6701
|
path: "api.assets.delete",
|
|
6686
|
-
client: "deleteAssets"
|
|
6702
|
+
client: "deleteAssets",
|
|
6703
|
+
inputFieldTypes: { assetIdsOrPrefixes: "array" }
|
|
6687
6704
|
}
|
|
6688
6705
|
];
|
|
6689
6706
|
const publicApiOperations = publicApiOperationInputs.map(withDefaultPermit);
|
|
@@ -7635,7 +7652,7 @@ class HandledCliError extends Error {
|
|
|
7635
7652
|
}
|
|
7636
7653
|
const isHandledCliError = (error) => error instanceof HandledCliError;
|
|
7637
7654
|
const name$N = "webstudio";
|
|
7638
|
-
const version = "0.274.
|
|
7655
|
+
const version = "0.274.5";
|
|
7639
7656
|
const description = "Webstudio CLI";
|
|
7640
7657
|
const author = "Webstudio <github@webstudio.is>";
|
|
7641
7658
|
const homepage = "https://webstudio.is";
|
|
@@ -7643,11 +7660,11 @@ const type = "module";
|
|
|
7643
7660
|
const bin = { "webstudio-cli": "./bin.js", "webstudio": "./bin.js" };
|
|
7644
7661
|
const imports = { "#cli": { "webstudio": "./src/cli.ts", "default": "./lib/cli.js" } };
|
|
7645
7662
|
const files = ["lib/*", "templates/*", "bin.js", "!*.{test,stories}.*"];
|
|
7646
|
-
const scripts = { "typecheck": "tsgo --noEmit", "generate-docs": "
|
|
7663
|
+
const scripts = { "typecheck": "tsgo --noEmit", "generate-docs": "tsx scripts/generate-docs.ts", "build": "pnpm generate-docs && rm -rf lib && vite build", "test": "vitest run" };
|
|
7647
7664
|
const license = "AGPL-3.0-or-later";
|
|
7648
7665
|
const engines = { "node": ">=22" };
|
|
7649
7666
|
const dependencies = { "@clack/prompts": "^0.10.0", "@emotion/hash": "^0.9.2", "@trpc/client": "^10.45.2", "@webstudio-is/http-client": "workspace:*", "@webstudio-is/project-migrations": "workspace:*", "@webstudio-is/protocol": "workspace:*", "acorn": "^8.14.1", "acorn-walk": "^8.3.4", "change-case": "^5.4.4", "chrome-launcher": "^1.2.1", "deepmerge": "^4.3.1", "env-paths": "^3.0.0", "fast-deep-equal": "^3.1.3", "immer": "^10.1.1", "nanoid": "^5.1.5", "p-limit": "^6.2.0", "parse5": "7.3.0", "picocolors": "^1.1.1", "reserved-identifiers": "^1.0.0", "tinyexec": "^0.3.2", "tus-js-client": "^4.3.1", "warn-once": "^0.1.1", "yargs": "^17.7.2", "zod": "^3.24.2" };
|
|
7650
|
-
const devDependencies = { "@cloudflare/vite-plugin": "^1.1.0", "@netlify/vite-plugin-react-router": "^1.0.1", "@react-router/dev": "^7.5.3", "@react-router/fs-routes": "^7.5.3", "@remix-run/cloudflare": "^2.16.5", "@remix-run/cloudflare-pages": "^2.16.5", "@remix-run/dev": "^2.16.5", "@remix-run/node": "^2.16.5", "@remix-run/react": "^2.16.5", "@remix-run/server-runtime": "^2.16.5", "@types/react": "^18.2.70", "@types/react-dom": "^18.2.25", "@types/yargs": "^17.0.33", "@vercel/react-router": "^1.1.0", "@vitejs/plugin-react": "^4.4.1", "@webstudio-is/css-engine": "workspace:*", "@webstudio-is/image": "workspace:*", "@webstudio-is/project-build": "workspace:*", "@webstudio-is/react-sdk": "workspace:*", "@webstudio-is/sdk": "workspace:*", "@webstudio-is/sdk-components-animation": "workspace:*", "@webstudio-is/sdk-components-react": "workspace:*", "@webstudio-is/sdk-components-react-radix": "workspace:*", "@webstudio-is/sdk-components-react-remix": "workspace:*", "@webstudio-is/sdk-components-react-router": "workspace:*", "@webstudio-is/tsconfig": "workspace:*", "@webstudio-is/wsauth": "workspace:*", "h3": "^1.15.1", "ipx": "^3.0.3", "isbot": "^5.1.25", "prettier": "3.5.3", "react": "18.3.0-canary-14898b6a9-20240318", "react-dom": "18.3.0-canary-14898b6a9-20240318", "react-router": "^7.5.3", "ts-expect": "^1.3.0", "vike": "^0.4.229", "vite": "^6.3.4", "vitest": "^3.1.2", "wrangler": "^3.63.2" };
|
|
7667
|
+
const devDependencies = { "@cloudflare/vite-plugin": "^1.1.0", "@netlify/vite-plugin-react-router": "^1.0.1", "@react-router/dev": "^7.5.3", "@react-router/fs-routes": "^7.5.3", "@remix-run/cloudflare": "^2.16.5", "@remix-run/cloudflare-pages": "^2.16.5", "@remix-run/dev": "^2.16.5", "@remix-run/node": "^2.16.5", "@remix-run/react": "^2.16.5", "@remix-run/server-runtime": "^2.16.5", "@types/mdast": "^4.0.4", "@types/react": "^18.2.70", "@types/react-dom": "^18.2.25", "@types/yargs": "^17.0.33", "@vercel/react-router": "^1.1.0", "@vitejs/plugin-react": "^4.4.1", "@webstudio-is/css-engine": "workspace:*", "@webstudio-is/image": "workspace:*", "@webstudio-is/project-build": "workspace:*", "@webstudio-is/react-sdk": "workspace:*", "@webstudio-is/sdk": "workspace:*", "@webstudio-is/sdk-components-animation": "workspace:*", "@webstudio-is/sdk-components-react": "workspace:*", "@webstudio-is/sdk-components-react-radix": "workspace:*", "@webstudio-is/sdk-components-react-remix": "workspace:*", "@webstudio-is/sdk-components-react-router": "workspace:*", "@webstudio-is/tsconfig": "workspace:*", "@webstudio-is/wsauth": "workspace:*", "h3": "^1.15.1", "ipx": "^3.0.3", "isbot": "^5.1.25", "mdast-util-directive": "^3.1.0", "mdast-util-from-markdown": "^2.0.3", "mdast-util-to-string": "^4.0.0", "micromark-extension-directive": "^4.0.0", "prettier": "3.5.3", "react": "18.3.0-canary-14898b6a9-20240318", "react-dom": "18.3.0-canary-14898b6a9-20240318", "react-router": "^7.5.3", "ts-expect": "^1.3.0", "vike": "^0.4.229", "vite": "^6.3.4", "vitest": "^3.1.2", "wrangler": "^3.63.2" };
|
|
7651
7668
|
const packageJson = {
|
|
7652
7669
|
name: name$N,
|
|
7653
7670
|
version,
|
|
@@ -8988,9 +9005,9 @@ const htmlToJsx = (html2) => {
|
|
|
8988
9005
|
}
|
|
8989
9006
|
return result;
|
|
8990
9007
|
};
|
|
8991
|
-
const createRemixFramework = async () => (await import("./framework-remix-
|
|
8992
|
-
const createReactRouterFramework = async () => (await import("./framework-react-router-
|
|
8993
|
-
const createVikeSsgFramework = async () => (await import("./framework-vike-ssg-
|
|
9008
|
+
const createRemixFramework = async () => (await import("./framework-remix-DPrszLh-.js")).createFramework();
|
|
9009
|
+
const createReactRouterFramework = async () => (await import("./framework-react-router-D_ph8aB5.js")).createFramework();
|
|
9010
|
+
const createVikeSsgFramework = async () => (await import("./framework-vike-ssg-BvV5cdbB.js")).createFramework();
|
|
8994
9011
|
const mergeJsonInto = async (sourcePath, destinationPath) => {
|
|
8995
9012
|
const sourceJson = await readFile(sourcePath, "utf8");
|
|
8996
9013
|
const destinationJson = await readFile(destinationPath, "utf8").catch(
|
|
@@ -10907,6 +10924,10 @@ class StdioServerTransport {
|
|
|
10907
10924
|
});
|
|
10908
10925
|
}
|
|
10909
10926
|
}
|
|
10927
|
+
const projectBuildDocs = {
|
|
10928
|
+
"mcp-startup-guidance": "Before editing a Webstudio project, read `webstudio://project/guide` and `webstudio://project/tools`, or call `meta.index` and `meta.guide`. Follow the guide: read ids and Builder breakpoints first, prefer semantic tools over `apply-patch`, use direct value tools for fixed text/props, use bindings only for dynamic expressions/resources/actions, quote fixed text for expression-backed fields such as page metadata and resource URLs, put page/resource update fields under `values`, do not edit generated files for normal content/design changes, and use `preview.start` plus screenshot/vision for visual work.\n"
|
|
10929
|
+
};
|
|
10930
|
+
const readProjectBuildDoc = (name2) => projectBuildDocs[name2];
|
|
10910
10931
|
const isRecord = (value2) => typeof value2 === "object" && value2 !== null;
|
|
10911
10932
|
const isScreenshotBrowser = (value2) => typeof value2 === "string" && screenshotBrowserChoices.includes(value2);
|
|
10912
10933
|
const getRequestParams = (request) => isRecord(request) && isRecord(request.params) ? request.params : {};
|
|
@@ -10944,13 +10965,34 @@ const getOperationInputSchema = (operation) => {
|
|
|
10944
10965
|
properties: Object.fromEntries(
|
|
10945
10966
|
operation.inputFields.map((field) => [
|
|
10946
10967
|
field,
|
|
10947
|
-
|
|
10948
|
-
description: `Public API input field \`${field}\`.`
|
|
10949
|
-
}
|
|
10968
|
+
getOperationInputFieldSchema(operation, field)
|
|
10950
10969
|
])
|
|
10951
10970
|
)
|
|
10952
10971
|
};
|
|
10953
10972
|
};
|
|
10973
|
+
const getOperationInputFieldSchema = (operation, field) => {
|
|
10974
|
+
var _a3;
|
|
10975
|
+
const description2 = `Public API input field \`${field}\`.`;
|
|
10976
|
+
if (((_a3 = operation.inputFieldTypes) == null ? void 0 : _a3[field]) === "array") {
|
|
10977
|
+
return {
|
|
10978
|
+
type: "array",
|
|
10979
|
+
description: description2,
|
|
10980
|
+
items: {}
|
|
10981
|
+
};
|
|
10982
|
+
}
|
|
10983
|
+
return { description: description2 };
|
|
10984
|
+
};
|
|
10985
|
+
const wrapMcpRootArrayInput = (operation, input2) => {
|
|
10986
|
+
var _a3;
|
|
10987
|
+
if (Array.isArray(input2) === false || operation.inputFields.length !== 1) {
|
|
10988
|
+
return input2;
|
|
10989
|
+
}
|
|
10990
|
+
const [field] = operation.inputFields;
|
|
10991
|
+
if (field !== void 0 && ((_a3 = operation.inputFieldTypes) == null ? void 0 : _a3[field]) === "array") {
|
|
10992
|
+
return { [field]: input2 };
|
|
10993
|
+
}
|
|
10994
|
+
return input2;
|
|
10995
|
+
};
|
|
10954
10996
|
const screenshotInputSchema = {
|
|
10955
10997
|
...emptyInputSchema,
|
|
10956
10998
|
description: "Capture a visual screenshot for AI vision review. Pass { url } for any URL or { path } after preview.start.",
|
|
@@ -11116,6 +11158,53 @@ const mcpArgumentExamples = {
|
|
|
11116
11158
|
text: "Launch faster"
|
|
11117
11159
|
}
|
|
11118
11160
|
],
|
|
11161
|
+
"update-page": [
|
|
11162
|
+
{
|
|
11163
|
+
pageId: "page-id",
|
|
11164
|
+
values: {
|
|
11165
|
+
title: '"Pricing"',
|
|
11166
|
+
meta: {
|
|
11167
|
+
description: '"Pricing plans"'
|
|
11168
|
+
}
|
|
11169
|
+
}
|
|
11170
|
+
}
|
|
11171
|
+
],
|
|
11172
|
+
"update-props": [
|
|
11173
|
+
{
|
|
11174
|
+
updates: [
|
|
11175
|
+
{
|
|
11176
|
+
instanceId: "button-id",
|
|
11177
|
+
name: "aria-label",
|
|
11178
|
+
type: "string",
|
|
11179
|
+
value: "Open menu"
|
|
11180
|
+
}
|
|
11181
|
+
]
|
|
11182
|
+
}
|
|
11183
|
+
],
|
|
11184
|
+
"bind-props": [
|
|
11185
|
+
{
|
|
11186
|
+
bindings: [
|
|
11187
|
+
{
|
|
11188
|
+
instanceId: "link-id",
|
|
11189
|
+
name: "href",
|
|
11190
|
+
binding: { type: "expression", value: "currentPost.url" }
|
|
11191
|
+
}
|
|
11192
|
+
]
|
|
11193
|
+
}
|
|
11194
|
+
],
|
|
11195
|
+
"create-resource": [
|
|
11196
|
+
{
|
|
11197
|
+
name: "Posts",
|
|
11198
|
+
method: "get",
|
|
11199
|
+
url: '"https://api.example.com/posts"'
|
|
11200
|
+
}
|
|
11201
|
+
],
|
|
11202
|
+
"update-resource": [
|
|
11203
|
+
{
|
|
11204
|
+
resourceId: "resource-id",
|
|
11205
|
+
values: { url: '"https://api.example.com/posts"' }
|
|
11206
|
+
}
|
|
11207
|
+
],
|
|
11119
11208
|
"update-styles": [
|
|
11120
11209
|
{
|
|
11121
11210
|
updates: [
|
|
@@ -11127,6 +11216,11 @@ const mcpArgumentExamples = {
|
|
|
11127
11216
|
]
|
|
11128
11217
|
}
|
|
11129
11218
|
],
|
|
11219
|
+
"delete-styles": [
|
|
11220
|
+
{
|
|
11221
|
+
deletions: [{ instanceId: "instance-id", property: "box-shadow" }]
|
|
11222
|
+
}
|
|
11223
|
+
],
|
|
11130
11224
|
"apply-patch": [
|
|
11131
11225
|
{
|
|
11132
11226
|
baseVersion: 12,
|
|
@@ -11662,12 +11756,15 @@ const filterCapabilities = (tools) => {
|
|
|
11662
11756
|
tools: capability.tools.filter((tool) => names.has(tool))
|
|
11663
11757
|
})).filter((capability) => capability.tools.length > 0);
|
|
11664
11758
|
};
|
|
11759
|
+
const startupGuidance = readProjectBuildDoc("mcp-startup-guidance").trim();
|
|
11760
|
+
const valuesVsBindingsRule = 'Use direct value tools for fixed text/props. Use bindings only for dynamic expressions, parameters, resources, or actions. Expression-backed fixed strings such as page metadata and resource URLs must be quoted JavaScript string literal expressions, for example "\\"Pricing\\"". Page and resource updates put changed fields under values.';
|
|
11665
11761
|
const getMetaIndex = (tools, guidance) => {
|
|
11666
11762
|
const names = new Set(tools.map((tool) => tool.name));
|
|
11667
11763
|
const canVerifyVisually = ["preview.start", "screenshot"].every(
|
|
11668
11764
|
(tool) => names.has(tool)
|
|
11669
11765
|
);
|
|
11670
11766
|
return {
|
|
11767
|
+
readThisFirst: startupGuidance,
|
|
11671
11768
|
startHere: ["meta.index", "meta.guide", "status", "permissions"].filter(
|
|
11672
11769
|
(tool) => names.has(tool)
|
|
11673
11770
|
),
|
|
@@ -11681,6 +11778,7 @@ const getMetaIndex = (tools, guidance) => {
|
|
|
11681
11778
|
"Operate on the configured project only.",
|
|
11682
11779
|
"Read ids before writing.",
|
|
11683
11780
|
"Prefer semantic tools over apply-patch.",
|
|
11781
|
+
valuesVsBindingsRule,
|
|
11684
11782
|
"Use status/refresh when cached data may be stale.",
|
|
11685
11783
|
guidance == null ? void 0 : guidance.visualVerificationRule
|
|
11686
11784
|
].filter((rule) => rule !== void 0),
|
|
@@ -11704,6 +11802,7 @@ const getMetaGuide = (brief, tools, guidance) => {
|
|
|
11704
11802
|
matches.some((tool) => tool.annotations.localCapable) ? "Call refresh if cached namespaces may be stale." : void 0,
|
|
11705
11803
|
"Use focused read tools to collect ids and current values.",
|
|
11706
11804
|
"Use the smallest semantic mutation tool that matches the requested change.",
|
|
11805
|
+
valuesVsBindingsRule,
|
|
11707
11806
|
"Use apply-patch only when no semantic mutation tool fits.",
|
|
11708
11807
|
canVerifyVisually && guidance !== void 0 ? guidance.getVisionWorkflowSummary({ includeDiff: canDiffScreenshots }) : void 0
|
|
11709
11808
|
].filter(Boolean),
|
|
@@ -11730,7 +11829,7 @@ const getMoreTools = (brief, tools) => ({
|
|
|
11730
11829
|
mcpExamples: tool.mcpExamples ?? [],
|
|
11731
11830
|
cliRequiredOptions: tool.cliRequiredOptions ?? [],
|
|
11732
11831
|
cliExamples: tool.cliExamples ?? [],
|
|
11733
|
-
inputNote:
|
|
11832
|
+
inputNote: `MCP tool arguments are public API input objects. Examples show intent, but do not imply MCP flag names. ${valuesVsBindingsRule}`,
|
|
11734
11833
|
annotations: tool.annotations
|
|
11735
11834
|
}))
|
|
11736
11835
|
});
|
|
@@ -11960,8 +12059,8 @@ const createProjectSessionMcpCore = ({
|
|
|
11960
12059
|
guidance
|
|
11961
12060
|
}) => {
|
|
11962
12061
|
let session;
|
|
11963
|
-
const
|
|
11964
|
-
operations.map((operation) => operation.command)
|
|
12062
|
+
const operationByCommand = new Map(
|
|
12063
|
+
operations.map((operation) => [operation.command, operation])
|
|
11965
12064
|
);
|
|
11966
12065
|
const listTools = () => listProjectSessionMcpTools(operations, {
|
|
11967
12066
|
includeImport: importProject2 !== void 0,
|
|
@@ -12066,12 +12165,14 @@ const createProjectSessionMcpCore = ({
|
|
|
12066
12165
|
if (name2 === "preview.status" && getPreviewStatus !== void 0) {
|
|
12067
12166
|
return toMetaResult(await getPreviewStatus());
|
|
12068
12167
|
}
|
|
12069
|
-
|
|
12168
|
+
const operation = operationByCommand.get(name2);
|
|
12169
|
+
if (operation === void 0) {
|
|
12070
12170
|
throw new Error(`Unknown MCP tool "${name2}".`);
|
|
12071
12171
|
}
|
|
12172
|
+
const operationInput = wrapMcpRootArrayInput(operation, input2);
|
|
12072
12173
|
const envelope = await executeOperation({
|
|
12073
12174
|
command: name2,
|
|
12074
|
-
input:
|
|
12175
|
+
input: operationInput,
|
|
12075
12176
|
dryRun
|
|
12076
12177
|
});
|
|
12077
12178
|
return toCallResult(envelope);
|
|
@@ -12134,7 +12235,7 @@ const createProjectSessionMcpServer = async ({
|
|
|
12134
12235
|
tools: {},
|
|
12135
12236
|
resources: {}
|
|
12136
12237
|
},
|
|
12137
|
-
instructions:
|
|
12238
|
+
instructions: startupGuidance
|
|
12138
12239
|
}
|
|
12139
12240
|
);
|
|
12140
12241
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
@@ -12201,13 +12302,110 @@ const createMcpStdioTransport = async ({
|
|
|
12201
12302
|
return new StdioServerTransport(stdin2, stdout2);
|
|
12202
12303
|
};
|
|
12203
12304
|
const cliDocs = {
|
|
12204
|
-
"api-use-cases": '# CLI API Use Cases\n\n## Link/configure one project\n\nCommands:\n\n- webstudio init --link <api-share-link> --json\n\nNotes:\n\n- Writes local project id and global origin/token config.\n\n## Import synced project bundle into another project\n\nCommands:\n\n- webstudio sync\n- webstudio import --to <destination-share-link>\n- MCP tool: import {"to":"<destination-share-link>"}\n\nNotes:\n\n- Imports local `.webstudio/data.json` into the destination project.\n- Destination share link must allow build/import access.\n- Use `--skip-assets` only when asset rows and files should not be imported.\n\n## Identify current token\n\nCommands:\n\n- MCP tool: whoami {}\n\n## Check token permissions\n\nCommands:\n\n- webstudio permissions --json\n\n## Inspect project/build/version\n\nCommands:\n\n- MCP tool: inspect {}\n- MCP tool: snapshot {"include":["pages","instances","styles"]}\n\n## Discover CLI/API capabilities\n\nCommands:\n\n- webstudio schema api --json\n- webstudio man api --json\n- webstudio man llm --json\n- webstudio man mcp --json\n- MCP tool: meta.index {}\n- MCP tool: meta.guide {"brief":"Create a pricing page"}\n- MCP tool: meta.get_more_tools {"brief":"update-styles"}\n\nNotes:\n\n- Use `tools/list` for machine-readable MCP tool schemas.\n- Use `resources/list` and `resources/read` for longer MCP resources such as `webstudio://project/tools` and `webstudio://project/guide`.\n\n## Inspect and refresh MCP session cache\n\nCommands:\n\n- MCP tool: status {}\n- MCP tool: refresh {"namespaces":["pages","instances","styles"]}\n- MCP tool: reset-session {}\n\nNotes:\n\n- Use status before a task to understand the cached ProjectSession state.\n- Use refresh when project data may have changed outside the current MCP session.\n- Use reset-session when local cached state is corrupt or incompatible.\n\n## Visually verify rendered work with AI vision\n\nCommands:\n\n- MCP tool: preview.start {"host":"127.0.0.1","port":5173}\n- MCP tool: preview.status {}\n- MCP tool: screenshot {"path":"/","output":"current.png","viewport":{"width":1440,"height":900},"waitUntil":"load","waitForTimeout":250}\n- MCP tool: screenshot.diff {"baselinePath":"before.png","currentPath":"current.png","outputDir":".webstudio/screenshots"}\n- MCP tool: vision.install-ocr {"confirm":true}\n\nNotes:\n\n- Use this after page/content/style mutations and after generated project files are current so a vision-capable AI can see what was actually built.\n- Use waitForSelector when the rendered app has a reliable ready marker, waitUntil:"networkidle" for network-heavy pages, and waitForTimeout only for final visual settling.\n- For a fresh checkout, copied fixture, or newly generated app, run npm install or pnpm install in the generated project before preview.start or webstudio preview.\n- If preview fails with a missing generated-app command/package such as react-router or vite, install the generated app dependencies and retry.\n- When a baseline exists, use screenshot.diff to get changed regions, OCR textAnalysis, and diff artifact paths before deciding whether the result matches.\n- If screenshot.diff reports OCR unavailable and the user agrees to install it, call vision.install-ocr {"confirm":true}; otherwise continue with pixel diff and visual inspection.\n- Compare the PNG, OCR text evidence, and diff artifacts against the user\'s intent for layout, typography, colors, spacing, imagery, and responsive framing; then iterate with focused mutations.\n- Root CLI equivalent: webstudio preview --template ssg, then webstudio screenshot <url> --output current.png.\n\n## List pages\n\nCommands:\n\n- MCP tool: list-pages {"includeFolders":true}\n\n## Read page by id\n\nCommands:\n\n- MCP tool: get-page {"pageId":"<pageId>"}\n\n## Read page by path\n\nCommands:\n\n- MCP tool: get-page-by-path {"path":"/pricing"}\n\n## Create page\n\nCommands:\n\n- MCP tool: create-page {"name":"Pricing","path":"/pricing"}\n\n## Update page settings/metadata\n\nCommands:\n\n- MCP tool: update-page {"pageId":"<pageId>","title":"Pricing","description":"Plans","status":"200"}\n- MCP tool: update-page {"pageId":"<pageId>","auth":{"login":"<login>","password":"<password>"}}\n\n## Read project settings\n\nCommands:\n\n- MCP tool: get-project-settings {}\n\n## Update project settings\n\nCommands:\n\n- MCP tool: update-project-settings {"settings":"project-settings.json contents"}\n\n## List redirects\n\nCommands:\n\n- MCP tool: list-redirects {}\n\n## Create redirect\n\nCommands:\n\n- MCP tool: create-redirect {"oldPath":"/old","newPath":"/new","status":301}\n\n## Update redirect\n\nCommands:\n\n- MCP tool: update-redirect {"oldPath":"/old","newPath":"/newer","status":302}\n- MCP tool: update-redirect {"oldPath":"/old","status":null}\n\n## Delete redirect\n\nCommands:\n\n- MCP tool: delete-redirect {"oldPath":"/old"}\n\n## List breakpoints\n\nCommands:\n\n- MCP tool: list-breakpoints {}\n\n## Create breakpoint\n\nCommands:\n\n- MCP tool: create-breakpoint {"breakpointId":"tablet","label":"Tablet","maxWidth":991}\n\n## Update breakpoint\n\nCommands:\n\n- MCP tool: update-breakpoint {"breakpointId":"tablet","label":"Tablet","maxWidth":1023}\n- MCP tool: update-breakpoint {"breakpointId":"tablet","condition":null,"minWidth":768}\n- MCP tool: update-breakpoint {"breakpointId":"tablet","minWidth":null,"maxWidth":null,"condition":"(hover: hover)"}\n\n## Delete breakpoint\n\nCommands:\n\n- MCP tool: delete-breakpoint {"breakpointId":"tablet","confirm":true}\n\n## Duplicate page\n\nCommands:\n\n- MCP tool: duplicate-page {"pageId":"<pageId>","name":"Pricing Copy","path":"/pricing-copy"}\n\n## List page templates\n\nCommands:\n\n- MCP tool: list-page-templates {}\n\n## Create page from template\n\nCommands:\n\n- MCP tool: create-page-from-template {"templateId":"<templateId>","name":"Landing","path":"/landing"}\n\n## Delete page\n\nCommands:\n\n- MCP tool: delete-page {"pageId":"<pageId>"}\n\n## List folders\n\nCommands:\n\n- MCP tool: list-folders {"includePages":true}\n\n## Create folder\n\nCommands:\n\n- MCP tool: create-folder {"name":"Blog","slug":"blog"}\n\n## Update folder\n\nCommands:\n\n- MCP tool: update-folder {"folderId":"<folderId>","name":"Blog","slug":"blog"}\n\n## Delete folder\n\nCommands:\n\n- MCP tool: delete-folder {"folderId":"<folderId>"}\n\n## List element instances\n\nCommands:\n\n- MCP tool: list-instances {"pagePath":"/","maxDepth":3}\n\n## Inspect one element instance\n\nCommands:\n\n- MCP tool: inspect-instance {"instanceId":"<instanceId>","include":["props","styles","children"]}\n\n## Append/prepend/replace child elements\n\nCommands:\n\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n\n## Move elements\n\nCommands:\n\n- MCP tool: move-instance {"moves":"moves.json contents"}\n\n## Clone element subtree\n\nCommands:\n\n- MCP tool: clone-instance {"sourceInstanceId":"<instanceId>","parentInstanceId":"<targetParentId>"}\n\n## Delete element subtree\n\nCommands:\n\n- MCP tool: delete-instance {"instanceId":"<instanceId>"}\n\n## List text/expression children\n\nCommands:\n\n- MCP tool: list-texts {"pagePath":"/"}\n\n## Update text child\n\nCommands:\n\n- MCP tool: update-text {"instanceId":"<instanceId>","childIndex":0,"text":"Launch faster"}\n\n## Update props\n\nCommands:\n\n- MCP tool: update-props {"updates":"props.json contents"}\n\n## Delete props\n\nCommands:\n\n- MCP tool: delete-props {"deletions":"props.json contents"}\n\n## Bind props to expressions/resources/actions\n\nCommands:\n\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n\n## Read styles\n\nCommands:\n\n- MCP tool: get-styles {"instanceId":"<instanceId>","includeTokens":true}\n\n## Update local styles\n\nCommands:\n\n- MCP tool: update-styles {"updates":"styles.json contents"}\n\n## Delete local styles\n\nCommands:\n\n- MCP tool: delete-styles {"deletions":"styles.json contents"}\n\n## Replace matching style values\n\nCommands:\n\n- MCP tool: replace-styles {"replacements":"replace.json contents"}\n\n## List design tokens\n\nCommands:\n\n- MCP tool: list-design-tokens {"withUsage":true}\n\n## Create design tokens\n\nCommands:\n\n- MCP tool: create-design-token {"tokens":"tokens.json contents"}\n\n## Update design token styles\n\nCommands:\n\n- MCP tool: update-design-token-styles {"styleSourceId":"<tokenId>","updates":"styles.json contents"}\n\n## Delete design token styles\n\nCommands:\n\n- MCP tool: delete-design-token-styles {"styleSourceId":"<tokenId>","deletions":"styles.json contents"}\n\n## Attach design token to instances\n\nCommands:\n\n- MCP tool: attach-design-token {"styleSourceId":"<tokenId>","instanceIds":"instances.json contents"}\n\n## Detach design token from instances\n\nCommands:\n\n- MCP tool: detach-design-token {"styleSourceId":"<tokenId>","instanceIds":"instances.json contents"}\n\n## Extract design token from local styles\n\nCommands:\n\n- MCP tool: extract-design-token {"token":"token.json contents"}\n\n## List CSS variables\n\nCommands:\n\n- MCP tool: list-css-variables {"withUsage":true}\n\n## Define CSS variables\n\nCommands:\n\n- MCP tool: define-css-variable {"variables":"vars.json contents"}\n\n## Delete CSS variables\n\nCommands:\n\n- MCP tool: delete-css-variable {"names":"names.json contents","confirm":true}\n\n## Rewrite CSS variable references\n\nCommands:\n\n- MCP tool: rewrite-css-variable-refs {"variables":"variables.json contents"}\n\n## List data variables\n\nCommands:\n\n- MCP tool: list-variables {}\n\n## Create data variable\n\nCommands:\n\n- MCP tool: create-variable {"scopeInstanceId":"<instanceId>","name":"title","value":{"type":"string","value":"Hello"}}\n\n## Update data variable\n\nCommands:\n\n- MCP tool: update-variable {"variableId":"<variableId>","value":{"type":"json","value":{"count":1}}}\n\n## Delete data variable\n\nCommands:\n\n- MCP tool: delete-variable {"variableId":"<variableId>"}\n\n## List resources\n\nCommands:\n\n- MCP tool: list-resources {}\n\n## Create resource\n\nCommands:\n\n- MCP tool: create-resource {"name":"Posts","method":"get","url":"https://api.example.com/posts"}\n\n## Update resource\n\nCommands:\n\n- MCP tool: update-resource {"resourceId":"<resourceId>","url":"https://api.example.com/posts"}\n\n## Delete resource\n\nCommands:\n\n- MCP tool: delete-resource {"resourceId":"<resourceId>"}\n\n## List assets\n\nCommands:\n\n- MCP tool: list-assets {"withUsage":true}\n\n## Upload one asset\n\nCommands:\n\n- MCP tool: upload-asset {"asset":"asset.json contents","assetsDir":".webstudio/assets"}\n\n## Upload asset batch\n\nCommands:\n\n- MCP tool: upload-assets {"assets":"assets.json contents","assetsDir":".webstudio/assets"}\n\n## Find asset usage\n\nCommands:\n\n- MCP tool: find-asset-usage {"assetId":"<assetId>"}\n\n## Replace asset references\n\nCommands:\n\n- MCP tool: replace-asset {"fromAssetId":"<oldAssetId>","toAssetId":"<newAssetId>","confirm":true}\n\n## Delete assets\n\nCommands:\n\n- MCP tool: delete-asset {"assetId":"<assetId>","confirm":true}\n\n## Publish project\n\nCommands:\n\n- webstudio publish deploy --target production --json\n\n## List publishes\n\nCommands:\n\n- webstudio publish list --json\n\n## Check publish job\n\nCommands:\n\n- webstudio publish status --job <buildId> --json\n\n## Unpublish\n\nCommands:\n\n- webstudio publish unpublish --target production --confirm --json\n\n## List domains\n\nCommands:\n\n- webstudio domains list --json\n\n## Create domain\n\nCommands:\n\n- webstudio domains create --domain example.com --json\n\n## Update domain\n\nCommands:\n\n- webstudio domains update --domain-id <domainId> --domain www.example.com --json\n\n## Delete domain\n\nCommands:\n\n- webstudio domains delete --domain-id <domainId> --confirm --json\n\n## Verify domain\n\nCommands:\n\n- webstudio domains verify --domain-id <domainId> --json\n\n## Make arbitrary store-level changes\n\nCommands:\n\n- MCP tool: inspect {}\n- MCP tool: snapshot {"include":["<namespace>"]}\n- MCP tool: apply-patch {"baseVersion":"<version>","transactions":"patch.json contents"}\n\nNotes:\n\n- Use only when no semantic command exists.\n\n## Manage marketplace metadata\n\nCommands:\n\n- MCP tool: snapshot {"include":["marketplaceProduct"]}\n- MCP tool: apply-patch {"baseVersion":"<version>","transactions":"patch.json contents"}\n\nPatch namespaces:\n\n- marketplaceProduct\n\n## Search and inspect safely\n\nCommands:\n\n- MCP tool: list-instances {"pagePath":"/","maxDepth":5}\n- MCP tool: inspect-instance {"instanceId":"<instanceId>","include":["props","styles","children"]}\n- MCP tool: list-texts {"pagePath":"/"}\n- MCP tool: list-assets {"withUsage":true}\n- MCP tool: find-asset-usage {"assetId":"<assetId>"}\n- MCP tool: snapshot {"include":["pages","instances","props","resources","assets"]}\n\nNotes:\n\n- Use this for finding elements by label, type, href/resource patterns, HTML snippets, missing accessibility metadata, or asset usage.\n\n## Refactor targeted content\n\nCommands:\n\n- MCP tool: list-instances {"pagePath":"/"}\n- MCP tool: list-texts {"pagePath":"/"}\n- MCP tool: update-text {"instanceId":"<instanceId>","childIndex":0,"text":"Launch faster"}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: update-page {"pageId":"<pageId>","title":"Pricing","description":"Plans"}\n- MCP tool: update-resource {"resourceId":"<resourceId>","url":"https://api.example.com/posts"}\n- MCP tool: replace-asset {"fromAssetId":"<oldAssetId>","toAssetId":"<newAssetId>","confirm":true}\n- MCP tool: replace-styles {"replacements":"replace.json contents"}\n- MCP tool: rewrite-css-variable-refs {"variables":"variables.json contents"}\n\nNotes:\n\n- Use focused reads first, then mutate only matching instances, props, metadata, resource URLs, assets, or style references.\n\n## Optimize existing project\n\nCommands:\n\n- MCP tool: list-pages {"includeFolders":true}\n- MCP tool: update-page {"pageId":"<pageId>","title":"Pricing","description":"Plans"}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: list-breakpoints {}\n- MCP tool: update-breakpoint {"breakpointId":"tablet","maxWidth":1023}\n- MCP tool: get-styles {"instanceId":"<instanceId>","includeTokens":true}\n- MCP tool: update-styles {"updates":"styles.json contents"}\n- MCP tool: attach-design-token {"styleSourceId":"<tokenId>","instanceIds":"instances.json contents"}\n- MCP tool: update-project-settings {"settings":"project-settings.json contents"}\n\nNotes:\n\n- Use this for SEO metadata, accessibility labels, responsive behavior, token consistency, and project settings.\n\n## Connect external data\n\nCommands:\n\n- MCP tool: create-variable {"scopeInstanceId":"<instanceId>","name":"title","value":{"type":"string","value":"Hello"}}\n- MCP tool: create-resource {"name":"Posts","method":"get","url":"https://api.example.com/posts"}\n- MCP tool: update-resource {"resourceId":"<resourceId>","url":"https://api.example.com/posts"}\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n\nNotes:\n\n- Use this for CMS sections, blog listings, Ghost/headless CMS pages, n8n-style integrations, and API URLs built from variables.\n\n## Support dynamic runtime behavior\n\nCommands:\n\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n- MCP tool: create-resource {"name":"Seats","method":"get","url":"https://api.example.com/seats"}\n- MCP tool: snapshot {"include":["instances","props","resources"]}\n- MCP tool: apply-patch {"baseVersion":"<version>","transactions":"patch.json contents"}\n\nNotes:\n\n- Use existing scripts/resources for behavior, then move presentational structure into editable Webstudio instances where possible.\n- There is no dedicated semantic command yet for converting script-generated UI into editable Webstudio structure.\n\n## Build authenticated pages\n\nCommands:\n\n- MCP tool: create-page {"name":"Account","path":"/account"}\n- MCP tool: update-page {"pageId":"<pageId>","auth":{"login":"<login>","password":"<password>"}}\n- MCP tool: create-resource {"name":"Session","method":"get","url":"https://api.example.com/session"}\n- MCP tool: create-variable {"scopeInstanceId":"<instanceId>","name":"user","value":{"type":"json","value":{}}}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n\nNotes:\n\n- Basic auth is semantic today. Provider-specific Supabase/Firebase setup still requires manual resources, props, embeds, or patches.\n\n## Generate from design input\n\nCommands:\n\n- MCP tool: create-page {"name":"Landing","path":"/landing"}\n- MCP tool: create-design-token {"tokens":"tokens.json contents"}\n- MCP tool: define-css-variable {"variables":"vars.json contents"}\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n- MCP tool: update-styles {"updates":"styles.json contents"}\n- MCP tool: preview.start {"host":"127.0.0.1","port":5173}\n- MCP tool: screenshot {"path":"/","output":"current.png","viewport":{"width":1440,"height":900},"waitUntil":"load","waitForTimeout":250}\n\nNotes:\n\n- Use this after external design interpretation. There is no dedicated import command for Figma, screenshots, Inception output, or design.md yet.\n\n## Cross-project maintenance\n\nCommands:\n\n- webstudio init --link <api-share-link> --json\n- webstudio permissions --json\n- webstudio mcp\n\nNotes:\n\n- Public API and CLI intentionally operate on one configured project at a time. Use an external script to loop over projects.\n\n# Known CLI Gaps\n\n## General project search and audit\n\nMissing:\nNo single semantic command searches across instance labels, props, hrefs, resource URLs, HTML embeds, asset references, and missing accessibility metadata.\n\nCurrent fallback:\nUse focused MCP reads such as list-instances, list-texts, list-assets, find-asset-usage, and snapshot.\n\nSuggested commands:\n\n- search-project\n- audit-accessibility\n- find-prop-usage\n\n## Save and manage page templates\n\nMissing:\nCLI can list page templates and create pages from existing templates, but cannot save a page as a template or update/delete templates semantically.\n\nCurrent fallback:\nUse MCP snapshot and apply-patch only when the template data model is understood.\n\nSuggested commands:\n\n- create-page-template\n- update-page-template\n- delete-page-template\n\n## Semantic marketplace metadata\n\nMissing:\nMarketplace metadata is only available through MCP snapshot/apply-patch, not dedicated semantic commands.\n\nCurrent fallback:\nUse MCP snapshot --include marketplaceProduct and apply-patch.\n\nSuggested commands:\n\n- get-marketplace\n- update-marketplace\n\n## Provider-specific authenticated pages\n\nMissing:\nCLI supports page basic auth and generic resources/props/embeds, but not guided Supabase/Firebase auth setup.\n\nCurrent fallback:\nCreate the page, resources, variables, props, and embeds manually with existing MCP semantic tools.\n\nSuggested commands:\n\n- setup-auth-page\n\n## Dynamic script/runtime integration helpers\n\nMissing:\nCLI can manipulate props/resources/embeds, but has no semantic workflow for converting script-generated UI into editable Webstudio structures.\n\nCurrent fallback:\nUse MCP append-instance, props, resources, and raw patch where necessary.\n\nSuggested commands:\n\n- integrate-runtime-ui\n\n## Generate from design input\n\nMissing:\nNo command imports Figma, screenshots, Inception output, or design.md and turns it into pages/tokens/layout.\n\nCurrent fallback:\nUse external generation, then apply semantic CLI commands or apply-patch.\n\nSuggested commands:\n\n- generate-from-design\n\n## Built-in cross-project maintenance\n\nMissing:\nPublic API and CLI intentionally operate on one configured project at a time; there is no built-in multi-project discovery or loop runner.\n\nCurrent fallback:\nRun the CLI from an external script that reconfigures one project/session at a time.\n\nSuggested commands:\n\n- none\n',
|
|
12205
|
-
"manual-api": '# Webstudio API CLI Manual\n\nThe API commands operate on the single project configured by:\n\n- .webstudio/config.json: projectId\n- global Webstudio config: origin and token\n\
|
|
12206
|
-
"manual-llm":
|
|
12207
|
-
"manual-mcp": "# Webstudio MCP Manual\n\n`webstudio mcp` starts a stdio MCP server for the configured project.\n\n## Startup\n\n1. Configure a project with `webstudio init --link <api-share-link> --json`.\n2. Check capabilities with `webstudio permissions --json`.\n3. Start the server with `webstudio mcp`.\n\nWhile the server is running, stdout is reserved for MCP JSON-RPC messages. Do not print human text from the server process.\n\n## Discovery\n\nUse MCP itself after startup:\n\n- `tools/list`: machine-readable available tools\n- `resources/list`: available longer JSON resources\n- `meta.index`: concise capability catalog\n- `meta.guide`: workflow for a user goal\n- `meta.get_more_tools`: detailed params, examples, namespaces, and local/server behavior\n\nUseful resources:\n\n- `webstudio://project/status`: current ProjectSession status\n- `webstudio://project/tools`: operation catalog\n- `webstudio://project/guide`: concise discovery guide\n\n## Core Rules\n\n- Operate on the configured project only.\n- Read ids before writing.\n- Prefer semantic tools over `apply-patch`.\n- Use `status` and `refresh` when cached namespaces may be stale.\n- A mutation is durable only when `meta.session.committed` is true.\n- For visual/design work, verify the rendered result with vision before finishing.\n\n## Vision Verification Loop\n\nVision-capable AI can use MCP to see what it is building:\n\n{{mcpVisionVerificationLoopMarkdown}}\n\nGenerated app setup:\n\n{{mcpGeneratedAppDependencyNotes}}\n\n## MCP Argument Examples\n\nMCP tools receive JSON argument objects:\n\n{{mcpArgumentExampleIndex}}\n\n## Screenshot Verification\n\n{{screenshotVerificationSummary}}\n",
|
|
12208
|
-
"mcp-
|
|
12305
|
+
"api-use-cases": '# CLI API Use Cases\n\n## Link/configure one project\n\nCommands:\n\n- webstudio init --link <api-share-link> --json\n\nNotes:\n\n- Writes local project id and global origin/token config.\n\n## Import synced project bundle into another project\n\nCommands:\n\n- webstudio sync\n- webstudio import --to <destination-share-link>\n- MCP tool: import {"to":"<destination-share-link>"}\n\nNotes:\n\n- Imports local `.webstudio/data.json` into the destination project.\n- Destination share link must allow build/import access.\n- Use `--skip-assets` only when asset rows and files should not be imported.\n\n## Identify current token\n\nCommands:\n\n- MCP tool: whoami {}\n\n## Check token permissions\n\nCommands:\n\n- webstudio permissions --json\n\n## Inspect project/build/version\n\nCommands:\n\n- MCP tool: inspect {}\n- MCP tool: snapshot {"include":["pages","instances","styles"]}\n\n## Discover CLI/API capabilities\n\nCommands:\n\n- webstudio schema api --json\n- webstudio man api --json\n- webstudio man llm --json\n- webstudio man mcp --json\n- MCP tool: meta.index {}\n- MCP tool: meta.guide {"brief":"Create a pricing page"}\n- MCP tool: meta.get_more_tools {"brief":"update-styles"}\n\nNotes:\n\n- Use `tools/list` for machine-readable MCP tool schemas.\n- Use `resources/list` and `resources/read` for longer MCP resources such as `webstudio://project/tools` and `webstudio://project/guide`.\n\n## Inspect and refresh MCP session cache\n\nCommands:\n\n- MCP tool: status {}\n- MCP tool: refresh {"namespaces":["pages","instances","styles"]}\n- MCP tool: reset-session {}\n\nNotes:\n\n- Use status before a task to understand the cached ProjectSession state.\n- Use refresh when project data may have changed outside the current MCP session.\n- Use reset-session when local cached state is corrupt or incompatible.\n\n## Visually verify rendered work with AI vision\n\nCommands:\n\n- MCP tool: preview.start {"host":"127.0.0.1","port":5173}\n- MCP tool: preview.status {}\n- MCP tool: screenshot {"path":"/","output":"current.png","viewport":{"width":1440,"height":900},"waitUntil":"load","waitForTimeout":250}\n- MCP tool: screenshot.diff {"baselinePath":"before.png","currentPath":"current.png","outputDir":".webstudio/screenshots"}\n- MCP tool: vision.install-ocr {"confirm":true}\n\nNotes:\n\n- Use this after page/content/style mutations and after generated project files are current so a vision-capable AI can see what was actually built.\n- Use waitForSelector when the rendered app has a reliable ready marker, waitUntil:"networkidle" for network-heavy pages, and waitForTimeout only for final visual settling.\n- For a fresh checkout, copied fixture, or newly generated app, run npm install or pnpm install in the generated project before preview.start or webstudio preview.\n- If preview fails with a missing generated-app command/package such as react-router or vite, install the generated app dependencies and retry.\n- When a baseline exists, use screenshot.diff to get changed regions, OCR textAnalysis, and diff artifact paths before deciding whether the result matches.\n- If screenshot.diff reports OCR unavailable and the user agrees to install it, call vision.install-ocr {"confirm":true}; otherwise continue with pixel diff and visual inspection.\n- Compare the PNG, OCR text evidence, and diff artifacts against the user\'s intent for layout, typography, colors, spacing, imagery, and responsive framing; then iterate with focused mutations.\n- Root CLI equivalent: webstudio preview --template ssg, then webstudio screenshot <url> --output current.png.\n\n## List pages\n\nCommands:\n\n- MCP tool: list-pages {"includeFolders":true}\n\n## Read page by id\n\nCommands:\n\n- MCP tool: get-page {"pageId":"<pageId>"}\n\n## Read page by path\n\nCommands:\n\n- MCP tool: get-page-by-path {"path":"/pricing"}\n\n## Create page\n\nCommands:\n\n- MCP tool: create-page {"name":"Pricing","path":"/pricing"}\n\n## Update page settings/metadata\n\nCommands:\n\n- MCP tool: update-page {"pageId":"<pageId>","values":{"title":"\\"Pricing\\"","meta":{"description":"\\"Plans\\"","status":"200"}}}\n- MCP tool: update-page {"pageId":"<pageId>","values":{"meta":{"auth":{"login":"<login>","password":"<password>"}}}}\n\nNotes:\n\n- Page title and metadata text fields are expression-backed. For fixed text, send a quoted JavaScript string literal expression such as `"\\"Pricing\\""`.\n\n## Read project settings\n\nCommands:\n\n- MCP tool: get-project-settings {}\n\n## Update project settings\n\nCommands:\n\n- MCP tool: update-project-settings {"settings":"project-settings.json contents"}\n\n## List redirects\n\nCommands:\n\n- MCP tool: list-redirects {}\n\n## Create redirect\n\nCommands:\n\n- MCP tool: create-redirect {"oldPath":"/old","newPath":"/new","status":301}\n\n## Update redirect\n\nCommands:\n\n- MCP tool: update-redirect {"oldPath":"/old","newPath":"/newer","status":302}\n- MCP tool: update-redirect {"oldPath":"/old","status":null}\n\n## Delete redirect\n\nCommands:\n\n- MCP tool: delete-redirect {"oldPath":"/old"}\n\n## List breakpoints\n\nCommands:\n\n- MCP tool: list-breakpoints {}\n\n## Create breakpoint\n\nCommands:\n\n- MCP tool: create-breakpoint {"breakpointId":"tablet","label":"Tablet","maxWidth":991}\n\n## Update breakpoint\n\nCommands:\n\n- MCP tool: update-breakpoint {"breakpointId":"tablet","label":"Tablet","maxWidth":1023}\n- MCP tool: update-breakpoint {"breakpointId":"tablet","condition":null,"minWidth":768}\n- MCP tool: update-breakpoint {"breakpointId":"tablet","minWidth":null,"maxWidth":null,"condition":"(hover: hover)"}\n\n## Delete breakpoint\n\nCommands:\n\n- MCP tool: delete-breakpoint {"breakpointId":"tablet","confirm":true}\n\n## Duplicate page\n\nCommands:\n\n- MCP tool: duplicate-page {"pageId":"<pageId>","name":"Pricing Copy","path":"/pricing-copy"}\n\n## List page templates\n\nCommands:\n\n- MCP tool: list-page-templates {}\n\n## Create page from template\n\nCommands:\n\n- MCP tool: create-page-from-template {"templateId":"<templateId>","name":"Landing","path":"/landing"}\n\n## Delete page\n\nCommands:\n\n- MCP tool: delete-page {"pageId":"<pageId>"}\n\n## List folders\n\nCommands:\n\n- MCP tool: list-folders {"includePages":true}\n\n## Create folder\n\nCommands:\n\n- MCP tool: create-folder {"name":"Blog","slug":"blog"}\n\n## Update folder\n\nCommands:\n\n- MCP tool: update-folder {"folderId":"<folderId>","name":"Blog","slug":"blog"}\n\n## Delete folder\n\nCommands:\n\n- MCP tool: delete-folder {"folderId":"<folderId>"}\n\n## List element instances\n\nCommands:\n\n- MCP tool: list-instances {"pagePath":"/","maxDepth":3}\n\n## Inspect one element instance\n\nCommands:\n\n- MCP tool: inspect-instance {"instanceId":"<instanceId>","include":["props","styles","children"]}\n\n## Append/prepend/replace child elements\n\nCommands:\n\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n\n## Move elements\n\nCommands:\n\n- MCP tool: move-instance {"moves":"moves.json contents"}\n\n## Clone element subtree\n\nCommands:\n\n- MCP tool: clone-instance {"sourceInstanceId":"<instanceId>","parentInstanceId":"<targetParentId>"}\n\n## Delete element subtree\n\nCommands:\n\n- MCP tool: delete-instance {"instanceId":"<instanceId>"}\n\n## List text/expression children\n\nCommands:\n\n- MCP tool: list-texts {"pagePath":"/"}\n\n## Update text child\n\nCommands:\n\n- MCP tool: update-text {"instanceId":"<instanceId>","childIndex":0,"text":"Launch faster"}\n\n## Update props\n\nCommands:\n\n- MCP tool: update-props {"updates":"props.json contents"}\n\nNotes:\n\n- Use this for fixed prop values such as `aria-label`, `alt`, `id`, static `href`, and other direct string/number/boolean/json prop values.\n- Do not use bindings just to set static text.\n\n## Delete props\n\nCommands:\n\n- MCP tool: delete-props {"deletions":"props.json contents"}\n\n## Bind props to expressions/resources/actions\n\nCommands:\n\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n\nNotes:\n\n- Use this only when the prop should remain dynamic: expression, parameter, resource, or action binding.\n- For a fixed string value, use `update-props` with `type:"string"` and a direct `value` instead.\n\n## Read styles\n\nCommands:\n\n- MCP tool: get-styles {"instanceId":"<instanceId>","includeTokens":true}\n\n## Update local styles\n\nCommands:\n\n- MCP tool: update-styles {"updates":"styles.json contents"}\n\n## Delete local styles\n\nCommands:\n\n- MCP tool: delete-styles {"deletions":"styles.json contents"}\n\n## Replace matching style values\n\nCommands:\n\n- MCP tool: replace-styles {"replacements":"replace.json contents"}\n\n## List design tokens\n\nCommands:\n\n- MCP tool: list-design-tokens {"withUsage":true}\n\n## Create design tokens\n\nCommands:\n\n- MCP tool: create-design-token {"tokens":"tokens.json contents"}\n\n## Update design token styles\n\nCommands:\n\n- MCP tool: update-design-token-styles {"styleSourceId":"<tokenId>","updates":"styles.json contents"}\n\n## Delete design token styles\n\nCommands:\n\n- MCP tool: delete-design-token-styles {"styleSourceId":"<tokenId>","deletions":"styles.json contents"}\n\n## Attach design token to instances\n\nCommands:\n\n- MCP tool: attach-design-token {"styleSourceId":"<tokenId>","instanceIds":"instances.json contents"}\n\n## Detach design token from instances\n\nCommands:\n\n- MCP tool: detach-design-token {"styleSourceId":"<tokenId>","instanceIds":"instances.json contents"}\n\n## Extract design token from local styles\n\nCommands:\n\n- MCP tool: extract-design-token {"token":"token.json contents"}\n\n## List CSS variables\n\nCommands:\n\n- MCP tool: list-css-variables {"withUsage":true}\n\n## Define CSS variables\n\nCommands:\n\n- MCP tool: define-css-variable {"variables":"vars.json contents"}\n\n## Delete CSS variables\n\nCommands:\n\n- MCP tool: delete-css-variable {"names":"names.json contents","confirm":true}\n\n## Rewrite CSS variable references\n\nCommands:\n\n- MCP tool: rewrite-css-variable-refs {"variables":"variables.json contents"}\n\n## List data variables\n\nCommands:\n\n- MCP tool: list-variables {}\n\n## Create data variable\n\nCommands:\n\n- MCP tool: create-variable {"scopeInstanceId":"<instanceId>","name":"title","value":{"type":"string","value":"Hello"}}\n\n## Update data variable\n\nCommands:\n\n- MCP tool: update-variable {"variableId":"<variableId>","value":{"type":"json","value":{"count":1}}}\n\n## Delete data variable\n\nCommands:\n\n- MCP tool: delete-variable {"variableId":"<variableId>"}\n\n## List resources\n\nCommands:\n\n- MCP tool: list-resources {}\n\n## Create resource\n\nCommands:\n\n- MCP tool: create-resource {"name":"Posts","method":"get","url":"\\"https://api.example.com/posts\\""}\n\n## Update resource\n\nCommands:\n\n- MCP tool: update-resource {"resourceId":"<resourceId>","values":{"url":"\\"https://api.example.com/posts\\""}}\n\n## Delete resource\n\nCommands:\n\n- MCP tool: delete-resource {"resourceId":"<resourceId>"}\n\n## List assets\n\nCommands:\n\n- MCP tool: list-assets {"withUsage":true}\n\n## Upload one asset\n\nCommands:\n\n- MCP tool: upload-asset {"asset":"asset.json contents","assetsDir":".webstudio/assets"}\n\n## Upload asset batch\n\nCommands:\n\n- MCP tool: upload-assets {"assets":"assets.json contents","assetsDir":".webstudio/assets"}\n\n## Find asset usage\n\nCommands:\n\n- MCP tool: find-asset-usage {"assetId":"<assetId>"}\n\n## Replace asset references\n\nCommands:\n\n- MCP tool: replace-asset {"fromAssetId":"<oldAssetId>","toAssetId":"<newAssetId>","confirm":true}\n\n## Delete assets\n\nCommands:\n\n- MCP tool: delete-asset {"assetId":"<assetId>","confirm":true}\n\n## Publish project\n\nCommands:\n\n- webstudio publish deploy --target production --json\n\n## List publishes\n\nCommands:\n\n- webstudio publish list --json\n\n## Check publish job\n\nCommands:\n\n- webstudio publish status --job <buildId> --json\n\n## Unpublish\n\nCommands:\n\n- webstudio publish unpublish --target production --confirm --json\n\n## List domains\n\nCommands:\n\n- webstudio domains list --json\n\n## Create domain\n\nCommands:\n\n- webstudio domains create --domain example.com --json\n\n## Update domain\n\nCommands:\n\n- webstudio domains update --domain-id <domainId> --domain www.example.com --json\n\n## Delete domain\n\nCommands:\n\n- webstudio domains delete --domain-id <domainId> --confirm --json\n\n## Verify domain\n\nCommands:\n\n- webstudio domains verify --domain-id <domainId> --json\n\n## Make arbitrary store-level changes\n\nCommands:\n\n- MCP tool: inspect {}\n- MCP tool: snapshot {"include":["<namespace>"]}\n- MCP tool: apply-patch {"baseVersion":"<version>","transactions":"patch.json contents"}\n\nNotes:\n\n- Use only when no semantic command exists.\n\n## Manage marketplace metadata\n\nCommands:\n\n- MCP tool: snapshot {"include":["marketplaceProduct"]}\n- MCP tool: apply-patch {"baseVersion":"<version>","transactions":"patch.json contents"}\n\nPatch namespaces:\n\n- marketplaceProduct\n\n## Search and inspect safely\n\nCommands:\n\n- MCP tool: list-instances {"pagePath":"/","maxDepth":5}\n- MCP tool: inspect-instance {"instanceId":"<instanceId>","include":["props","styles","children"]}\n- MCP tool: list-texts {"pagePath":"/"}\n- MCP tool: list-assets {"withUsage":true}\n- MCP tool: find-asset-usage {"assetId":"<assetId>"}\n- MCP tool: snapshot {"include":["pages","instances","props","resources","assets"]}\n\nNotes:\n\n- Use this for finding elements by label, type, href/resource patterns, HTML snippets, missing accessibility metadata, or asset usage.\n\n## Refactor targeted content\n\nCommands:\n\n- MCP tool: list-instances {"pagePath":"/"}\n- MCP tool: list-texts {"pagePath":"/"}\n- MCP tool: update-text {"instanceId":"<instanceId>","childIndex":0,"text":"Launch faster"}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: update-page {"pageId":"<pageId>","values":{"title":"\\"Pricing\\"","meta":{"description":"\\"Plans\\""}}}\n- MCP tool: update-resource {"resourceId":"<resourceId>","values":{"url":"\\"https://api.example.com/posts\\""}}\n- MCP tool: replace-asset {"fromAssetId":"<oldAssetId>","toAssetId":"<newAssetId>","confirm":true}\n- MCP tool: replace-styles {"replacements":"replace.json contents"}\n- MCP tool: rewrite-css-variable-refs {"variables":"variables.json contents"}\n\nNotes:\n\n- Use focused reads first, then mutate only matching instances, props, metadata, resource URLs, assets, or style references.\n\n## Optimize existing project\n\nCommands:\n\n- MCP tool: list-pages {"includeFolders":true}\n- MCP tool: update-page {"pageId":"<pageId>","values":{"title":"\\"Pricing\\"","meta":{"description":"\\"Plans\\""}}}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: list-breakpoints {}\n- MCP tool: update-breakpoint {"breakpointId":"tablet","maxWidth":1023}\n- MCP tool: get-styles {"instanceId":"<instanceId>","includeTokens":true}\n- MCP tool: update-styles {"updates":"styles.json contents"}\n- MCP tool: attach-design-token {"styleSourceId":"<tokenId>","instanceIds":"instances.json contents"}\n- MCP tool: update-project-settings {"settings":"project-settings.json contents"}\n\nNotes:\n\n- Use this for SEO metadata, accessibility labels, responsive behavior, token consistency, and project settings.\n\n## Connect external data\n\nCommands:\n\n- MCP tool: create-variable {"scopeInstanceId":"<instanceId>","name":"title","value":{"type":"string","value":"Hello"}}\n- MCP tool: create-resource {"name":"Posts","method":"get","url":"\\"https://api.example.com/posts\\""}\n- MCP tool: update-resource {"resourceId":"<resourceId>","values":{"url":"\\"https://api.example.com/posts\\""}}\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n\nNotes:\n\n- Use this for CMS sections, blog listings, Ghost/headless CMS pages, n8n-style integrations, and API URLs built from variables.\n\n## Support dynamic runtime behavior\n\nCommands:\n\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n- MCP tool: create-resource {"name":"Seats","method":"get","url":"\\"https://api.example.com/seats\\""}\n- MCP tool: snapshot {"include":["instances","props","resources"]}\n- MCP tool: apply-patch {"baseVersion":"<version>","transactions":"patch.json contents"}\n\nNotes:\n\n- Use existing scripts/resources for behavior, then move presentational structure into editable Webstudio instances where possible.\n- There is no dedicated semantic command yet for converting script-generated UI into editable Webstudio structure.\n\n## Build authenticated pages\n\nCommands:\n\n- MCP tool: create-page {"name":"Account","path":"/account"}\n- MCP tool: update-page {"pageId":"<pageId>","values":{"meta":{"auth":{"login":"<login>","password":"<password>"}}}}\n- MCP tool: create-resource {"name":"Session","method":"get","url":"\\"https://api.example.com/session\\""}\n- MCP tool: create-variable {"scopeInstanceId":"<instanceId>","name":"user","value":{"type":"json","value":{}}}\n- MCP tool: update-props {"updates":"props.json contents"}\n- MCP tool: bind-props {"bindings":"bindings.json contents"}\n\nNotes:\n\n- Basic auth is semantic today. Provider-specific Supabase/Firebase setup still requires manual resources, props, embeds, or patches.\n\n## Generate from design input\n\nCommands:\n\n- MCP tool: create-page {"name":"Landing","path":"/landing"}\n- MCP tool: create-design-token {"tokens":"tokens.json contents"}\n- MCP tool: define-css-variable {"variables":"vars.json contents"}\n- MCP tool: append-instance {"parentInstanceId":"<instanceId>","children":"children.json contents"}\n- MCP tool: update-styles {"updates":"styles.json contents"}\n- MCP tool: preview.start {"host":"127.0.0.1","port":5173}\n- MCP tool: screenshot {"path":"/","output":"current.png","viewport":{"width":1440,"height":900},"waitUntil":"load","waitForTimeout":250}\n\nNotes:\n\n- Use this after external design interpretation. There is no dedicated import command for Figma, screenshots, Inception output, or design.md yet.\n\n## Cross-project maintenance\n\nCommands:\n\n- webstudio init --link <api-share-link> --json\n- webstudio permissions --json\n- webstudio mcp\n\nNotes:\n\n- Public API and CLI intentionally operate on one configured project at a time. Use an external script to loop over projects.\n\n# Known CLI Gaps\n\n## General project search and audit\n\nMissing:\nNo single semantic command searches across instance labels, props, hrefs, resource URLs, HTML embeds, asset references, and missing accessibility metadata.\n\nCurrent fallback:\nUse focused MCP reads such as list-instances, list-texts, list-assets, find-asset-usage, and snapshot.\n\nSuggested commands:\n\n- search-project\n- audit-accessibility\n- find-prop-usage\n\n## Save and manage page templates\n\nMissing:\nCLI can list page templates and create pages from existing templates, but cannot save a page as a template or update/delete templates semantically.\n\nCurrent fallback:\nUse MCP snapshot and apply-patch only when the template data model is understood.\n\nSuggested commands:\n\n- create-page-template\n- update-page-template\n- delete-page-template\n\n## Semantic marketplace metadata\n\nMissing:\nMarketplace metadata is only available through MCP snapshot/apply-patch, not dedicated semantic commands.\n\nCurrent fallback:\nUse MCP snapshot --include marketplaceProduct and apply-patch.\n\nSuggested commands:\n\n- get-marketplace\n- update-marketplace\n\n## Provider-specific authenticated pages\n\nMissing:\nCLI supports page basic auth and generic resources/props/embeds, but not guided Supabase/Firebase auth setup.\n\nCurrent fallback:\nCreate the page, resources, variables, props, and embeds manually with existing MCP semantic tools.\n\nSuggested commands:\n\n- setup-auth-page\n\n## Dynamic script/runtime integration helpers\n\nMissing:\nCLI can manipulate props/resources/embeds, but has no semantic workflow for converting script-generated UI into editable Webstudio structures.\n\nCurrent fallback:\nUse MCP append-instance, props, resources, and raw patch where necessary.\n\nSuggested commands:\n\n- integrate-runtime-ui\n\n## Generate from design input\n\nMissing:\nNo command imports Figma, screenshots, Inception output, or design.md and turns it into pages/tokens/layout.\n\nCurrent fallback:\nUse external generation, then apply semantic CLI commands or apply-patch.\n\nSuggested commands:\n\n- generate-from-design\n\n## Built-in cross-project maintenance\n\nMissing:\nPublic API and CLI intentionally operate on one configured project at a time; there is no built-in multi-project discovery or loop runner.\n\nCurrent fallback:\nRun the CLI from an external script that reconfigures one project/session at a time.\n\nSuggested commands:\n\n- none\n',
|
|
12306
|
+
"manual-api": '# Webstudio API CLI Manual\n\nThe API commands operate on the single project configured by:\n\n- .webstudio/config.json: projectId\n- global Webstudio config: origin and token\n\n- Pass --json to API/discovery commands that support it. Do not add --json to top-level commands unless their help/schema documents it.\n- Never pass a project id. Commands use configured project only.\n- Read ids before writing. Do not invent ids for existing records.\n- stdout is one JSON object. stderr is diagnostics.\n- Prefer MCP semantic tools for detailed project edits. Use MCP apply-patch only when no semantic tool exists.\n\n## Start\n\n{{start}}\n\n## Read First\n\n{{readFirst}}\n\n## Project Session Cache\n\n- CLI commands use one local ProjectSession snapshot for the configured project.\n- Local-capable reads use cached namespaces when compatible and fetch only missing or stale namespaces.\n- Local-capable mutations build patches from the local snapshot, then commit with the cached build version.\n- Successful mutation commits update the local snapshot only after the remote commit succeeds.\n- Server-only commands run remotely and invalidate/refetch namespaces declared by the operation catalog.\n- Use --refresh on local-capable commands to refresh required namespaces before running.\n- Successful JSON responses include meta.session with operationId, buildId, version, source, committed, compatibility, namespace freshness, and diagnostics.\n\n## CLI Capability Inventory\n\n### Top-Level Commands\n\n{{topLevelCapabilityIndex}}\n\n### High-Level API Commands By Area\n\n{{apiCapabilityIndex}}\n\n### MCP-Only Operations\n\nThese are intentionally exposed through `webstudio mcp`, not as top-level shell commands:\n\n{{mcpOnlyCommandIndex}}\n\n## Task Recipes\n\n{{taskRecipeIndex}}\n\n## Use Case Index\n\n{{useCaseIndex}}\n\n## Known CLI Gaps\n\n{{knownCliGapIndex}}\n\n## Input File Shapes\n\n{{inputFileShapeIndex}}\n\n## Raw Patch Fallback\n\napply-patch accepts either BuildPatchTransaction[] or { "transactions": BuildPatchTransaction[] }.\n\nEach transaction has:\n\n{\n"id": "unique-client-transaction-id",\n"payload": [\n{\n"namespace": "pages",\n"patches": [\n{ "op": "replace", "path": ["meta", "siteName"], "value": "New Site" }\n]\n}\n]\n}\n\nPatch paths are JSON-patch-like paths into Builder store data. Map-like namespaces use ids as the first path item.\n\nSupported namespaces:\n\n- pages: site metadata, redirects, page records, folders, compiler settings\n- instances: element instances and children, including text/expression children\n- props: element props, bindings, page references, resource bindings\n- styles: CSS declarations keyed by style declaration key\n- styleSources: local style sources and reusable design tokens\n- styleSourceSelections: instance-to-style-source connections\n- dataSources: data variables, parameters, and resource data sources\n- resources: data resource definitions\n- assets: project asset records handled by the existing asset patch path\n- breakpoints: responsive breakpoints\n- marketplaceProduct: marketplace metadata\n\nCommit raw patch:\n\nMCP tool: apply-patch\n\n## Raw Patch Examples\n\nRename the site:\n\n[\n{\n"id": "tx-site-name",\n"payload": [\n{\n"namespace": "pages",\n"patches": [\n{ "op": "add", "path": ["meta", "siteName"], "value": "Acme Studio" }\n]\n}\n]\n}\n]\n\nUpdate page title metadata:\n\n[\n{\n"id": "tx-page-title",\n"payload": [\n{\n"namespace": "pages",\n"patches": [\n{ "op": "replace", "path": ["pages", "page-id", "meta", "title"], "value": "Pricing" }\n]\n}\n]\n}\n]\n\nUpdate a text child on an element:\n\n[\n{\n"id": "tx-text",\n"payload": [\n{\n"namespace": "instances",\n"patches": [\n{ "op": "replace", "path": ["instance-id", "children", 0, "value"], "value": "Launch faster" }\n]\n}\n]\n}\n]\n\nCreate a data variable:\n\n[\n{\n"id": "tx-variable",\n"payload": [\n{\n"namespace": "dataSources",\n"patches": [\n{\n"op": "add",\n"path": ["variable-id"],\n"value": {\n"type": "variable",\n"id": "variable-id",\n"scopeInstanceId": "instance-id",\n"name": "headline",\n"value": { "type": "string", "value": "Launch faster" }\n}\n}\n]\n}\n]\n}\n]\n\nCreate a design token:\n\n[\n{\n"id": "tx-token",\n"payload": [\n{\n"namespace": "styleSources",\n"patches": [\n{ "op": "add", "path": ["token-id"], "value": { "type": "token", "id": "token-id", "name": "Brand Primary" } }\n]\n},\n{\n"namespace": "styles",\n"patches": [\n{\n"op": "add",\n"path": ["token-id:base:color:"],\n"value": {\n"styleSourceId": "token-id",\n"breakpointId": "base",\n"property": "color",\n"value": { "type": "keyword", "value": "red" }\n}\n}\n]\n}\n]\n}\n]\n\n## Safety Rules\n\n- For MCP apply-patch, read the latest version with MCP snapshot before writing.\n- Reuse ids from MCP snapshot output when updating existing records.\n- Generate new unique ids when adding records.\n- If apply-patch reports a version conflict, read the latest build and regenerate the patch.\n- Prefer semantic MCP read tools for discovery, then use MCP snapshot for exact patch paths.\n\n## Command Index\n\n{{commandIndex}}\n',
|
|
12307
|
+
"manual-llm": '# Webstudio CLI Manual for LLMs\n\nUse this order. Stop only when a command returns ok:false.\n\n## Always\n\n1. webstudio permissions --json\n2. webstudio mcp\n3. Read MCP resource webstudio://project/tools.\n4. Pick focused MCP read tool.\n5. Pick semantic MCP write tool.\n\n## LLM Implementation Process\n\nUse this process for user requests that change Webstudio content, layout, styles, assets, pages, redirects, resources, or publishing state:\n\n1. Discover capabilities with `webstudio man llm --json`, `webstudio schema api --json`, and MCP `meta.index` or `webstudio://project/tools`.\n2. Inspect current project state with semantic reads such as `list-pages`, `get-page-by-path`, `list-instances`, `inspect-instance`, `get-styles`, `list-assets`, `list-breakpoints`, and `snapshot` only when needed.\n3. Mutate the Webstudio project with semantic MCP write tools first. Prefer `append-instance`, `update-text`, `update-props`, `update-styles`, `upload-asset`, `create-page`, and page/project settings tools over raw patches.\n4. Use `apply-patch` only when no semantic tool covers the required change, and only after reading the latest snapshot/version.\n5. For visual/design work, regenerate or preview the generated app, capture a screenshot, inspect it with vision, and iterate before final response.\n6. Report what changed and what verification ran.\n\n## Visual Design Workflow\n\nFor requests involving visible HTML/CSS, layout, typography, colors, imagery, responsive behavior, or screenshots:\n\n1. Read editable Webstudio structure first: pages, instances, props, styles, breakpoints, assets, and relevant text.\n2. Do not use generated route/component files as the source of truth for editable content.\n3. Make edits through Webstudio semantic commands/MCP tools so the result stays editable in Builder and survives the next `webstudio build`.\n4. Keep generated project files current, start preview, and capture the changed page with `screenshot`.\n5. Use `screenshot.diff` when a baseline exists and inspect screenshot/diff artifacts with vision before finishing.\n6. If vision or screenshot tooling is unavailable, state that explicitly and explain what fallback verification was used.\n\n## Responsive Verification Workflow\n\nFor responsive page work, use Builder breakpoints as the source of truth:\n\n1. Read breakpoints with `list-breakpoints` before deciding responsive behavior.\n2. Apply responsive styles with existing Builder breakpoint ids; do not invent CSS media queries or breakpoint names when Webstudio breakpoint data exists.\n3. Pick screenshot viewport widths from the project breakpoints: include a desktop width, each defined max-width or min-width edge, and a narrow mobile width.\n4. Capture each viewport with `screenshot`, for example `{"path":"/","output":"home-375.png","viewport":{"width":375,"height":812}}` and `{"path":"/","output":"home-1440.png","viewport":{"width":1440,"height":900}}`.\n5. Inspect every viewport screenshot with vision before finishing, checking layout, overflow, hidden content, text wrapping, and breakpoint-specific style changes.\n6. If any viewport fails, update styles through semantic Webstudio tools and repeat screenshots for the affected breakpoints.\n\n## Generated Files Guardrails\n\n- Do not edit `app/__generated__`, generated route files, generated page files, generated CSS, or build output for normal Webstudio content/design requests.\n- Do not replace generated page components with handcrafted app code unless the user explicitly asks for code-only export customization.\n- Generated files are build artifacts and may be overwritten by `webstudio build`.\n- If a task truly requires generated app customization, keep it outside `app/__generated__` where possible and explain that it is not editable Webstudio content.\n\n## Values vs Bindings\n\n- Use direct value tools for fixed content. For visible text, use `update-text` with plain `text`. For static props such as `aria-label`, `alt`, `id`, `class`, `href`, or button labels stored as props, use `update-props` with the prop\'s direct type/value.\n- Use `bind-props` only when the prop must stay dynamic: an expression, parameter, resource result, or action. Do not use `bind-props` just to set a fixed string.\n- Direct prop string example: `{"updates":[{"instanceId":"button-id","name":"aria-label","type":"string","value":"Open menu"}]}`.\n- Expression binding example: `{"bindings":[{"instanceId":"link-id","name":"href","binding":{"type":"expression","value":"currentPost.url"}}]}`.\n- Page metadata fields such as `title`, `description`, `language`, `redirect`, `status`, and custom meta content are expression-backed strings. For fixed text, pass a JavaScript string literal expression with JSON quoting, for example `JSON.stringify("Pricing | Acme")` in code or `"\\"Pricing | Acme\\""` in JSON. Never pass raw multi-word text such as `"Pricing | Acme"` as an expression.\n- Page metadata update example: use `update-page` with `{"pageId":"page-id","values":{"title":"\\"Pricing | Acme\\"","meta":{"description":"\\"Plans for teams\\""}}}`.\n- Resource URL, header, search-param, and body fields are also expression-backed. For a fixed URL, use a string literal expression such as `"\\"https://api.example.com/items\\""`.\n- Resource update example: use `update-resource` with `{"resourceId":"resource-id","values":{"url":"\\"https://api.example.com/items\\""}}`.\n\n## Pick Read Command\n\n{{readFirst}}\n\n## Pick Write Command\n\n{{taskRecipeIndex}}\n\n## Raw Patch Only If Needed\n\n1. Use MCP tool: snapshot.\n2. Write BuildPatchTransaction[].\n3. Use MCP tool: apply-patch.\n\n## MCP Argument Examples\n\nMCP tools receive JSON argument objects, not CLI flags. Use these shapes:\n\n{{mcpArgumentExampleIndex}}\n\n## Rules\n\n- Never guess ids for existing records. Read them first.\n- Never use project ids from user input. Commands use the configured project.\n- Use --refresh before a local-capable command when cached data may be stale.\n- Pass --json only to commands whose help/schema documents it. Do not add --json to top-level commands such as sync unless supported.\n- On VERSION_CONFLICT, read MCP snapshot again, regenerate the patch, then retry.\n- Treat stdout JSON as the API contract and stderr as diagnostics.\n- For visual/design work, verify the rendered result with vision before finishing.\n- Do not edit generated files for normal Webstudio content/design requests.\n- Use direct values for static strings and bindings only for dynamic expressions/resources/actions.\n- For expression-backed fields that need fixed text, encode the fixed text as a quoted JavaScript string literal expression.\n- Confirm destructive commands with --confirm only when user requested deletion/unpublish/replacement.\n- Use webstudio schema api --json for machine-readable command metadata.\n\n## Known Gaps\n\n{{knownCliGapIndex}}\n',
|
|
12308
|
+
"manual-mcp": "# Webstudio MCP Manual\n\n`webstudio mcp` starts a stdio MCP server for the configured project.\n\n## Startup\n\n1. Configure a project with `webstudio init --link <api-share-link> --json`.\n2. Check capabilities with `webstudio permissions --json`.\n3. Start the server with `webstudio mcp`.\n4. In the MCP client, read `webstudio://project/guide` before editing, or call `meta.index` and `meta.guide`.\n\nWhile the server is running, stdout is reserved for MCP JSON-RPC messages. Do not print human text from the server process.\n\n## Discovery\n\nUse MCP itself after startup:\n\n- `tools/list`: machine-readable available tools\n- `resources/list`: available longer JSON resources\n- `meta.index`: concise capability catalog\n- `meta.guide`: workflow for a user goal\n- `meta.get_more_tools`: detailed params, examples, namespaces, and local/server behavior\n\nUseful resources:\n\n- `webstudio://project/status`: current ProjectSession status\n- `webstudio://project/tools`: operation catalog\n- `webstudio://project/guide`: concise discovery guide\n\n## Core Rules\n\n- stdout is reserved for MCP JSON-RPC while the server is running.\n- Operate on the configured project only.\n- Read ids before writing.\n- Prefer semantic tools over `apply-patch`.\n- Use `status` and `refresh` when cached namespaces may be stale.\n- A mutation is durable only when `meta.session.committed` is true.\n- For visual/design work, verify the rendered result with vision before finishing.\n\n## Vision Verification Loop\n\nVision-capable AI can use MCP to see what it is building:\n\n{{mcpVisionVerificationLoopMarkdown}}\n\nGenerated app setup:\n\n{{mcpGeneratedAppDependencyNotes}}\n\n## MCP Argument Examples\n\nMCP tools receive JSON argument objects:\n\n{{mcpArgumentExampleIndex}}\n\n## Screenshot Verification\n\n{{screenshotVerificationSummary}}\n",
|
|
12309
|
+
"mcp-startup-epilogue": "Plain `webstudio mcp` starts the stdio MCP server.\n\nStartup marks cached ProjectSession data stale so MCP tools read the current Builder dev build.\n\nAfter startup, read MCP resource `webstudio://project/guide` before editing.\n\nAfter startup, MCP clients discover capabilities with `tools/list`, `resources/list`, `meta.index`, `meta.guide`, and `meta.get_more_tools`.\n\nstdout is reserved for MCP JSON-RPC messages while the server is running.\n",
|
|
12310
|
+
"mcp-vision": '# MCP Vision Verification\n\n## Generated App Dependency Notes\n\n- For a fresh checkout, copied fixture, or newly generated app, run npm install or pnpm install in the generated project before preview.start or webstudio preview.\n- If preview fails with a missing generated-app command/package such as react-router or vite, install the generated app dependencies and retry.\n\n## Visual Verification Rule\n\nFor visual/design work, use preview.start and screenshot after generated project files are current and generated app dependencies are installed so vision can inspect the rendered result before finishing. When a baseline exists, use screenshot.diff to get pixel regions, OCR text changes, and diff PNG artifacts.\n\n## Vision Verification Loop\n\n- Make focused page/content/style changes with semantic MCP tools.\n- Make sure generated project files are current and generated app dependencies are installed, then call preview.start once to keep the generated site running.\n- {{dependency-notes}}\n- For responsive work, call list-breakpoints first, then capture screenshots at viewport widths based on the Builder breakpoints plus a narrow mobile and desktop width.\n- Call screenshot with { path: "/" } or the changed page path and viewport such as { width: 375, height: 812 } and { width: 1440, height: 900 }. Use waitForSelector when the page has a reliable ready marker, waitUntil:"networkidle" for network-heavy pages, and waitForTimeout only for final visual settling.\n- {{diff}} When a baseline PNG exists, call screenshot.diff with baselinePath, currentPath, and outputDir.\n- {{diff}} Read screenshot.diff textAnalysis: it reports OCR status plus text that appeared, disappeared, moved, changed content, or changed font/style geometry. If OCR is unavailable, ask the user for permission to install Tesseract, then call vision.install-ocr with { "confirm": true }, or rely on visual inspection.\n- Inspect every viewport PNG and any diff artifacts with vision, then compare layout, OCR text evidence, color, spacing, imagery, and responsive framing against the user intent.\n- If the screenshot does not match, apply another focused mutation and repeat screenshot verification.\n\n## Workflow Summary With Diff\n\nFor visual/design work, make sure generated project files are current and generated app dependencies are installed, call preview.start, then screenshot({ path, viewport }); for responsive work, use list-breakpoints and capture the changed page at Builder breakpoint widths plus mobile and desktop widths; use screenshot.diff when a baseline exists, then inspect pixel regions, OCR textAnalysis, and PNG/diff artifacts with vision before finishing.\n\n## Workflow Summary Without Diff\n\nFor visual/design work, make sure generated project files are current and generated app dependencies are installed, call preview.start, then screenshot({ path, viewport }); for responsive work, use list-breakpoints and capture the changed page at Builder breakpoint widths plus mobile and desktop widths; inspect every PNG with vision before finishing.\n\n## Screenshot Verification Summary\n\nInside MCP, prefer preview.start plus screenshot({ path: "/", viewport }) after generated project files are current and generated app dependencies are installed, so the preview server stays running for fast repeated checks. For responsive work, read list-breakpoints and capture viewport widths from Builder breakpoint edges plus mobile and desktop widths before using vision. Screenshot waits for load by default, then fonts and two layout frames; pass waitForSelector for app readiness, waitUntil:"networkidle" for network-heavy pages, and waitForTimeout for final settling. When a baseline exists, use screenshot.diff for changed regions, OCR textAnalysis, and diff artifacts. Outside MCP, use webstudio preview and webstudio screenshot <url> --output current.png.\n\n## Screenshot Diff Evidence\n\n- Pixel evidence: total mismatch, changed regions, dominant color/luminance direction, diffPath, and contextDiffPath.\n- OCR evidence: textAnalysis.status, provider, and changes for appeared/disappeared/content_changed/moved/font_changed text.\n- OCR dependency: screenshot.diff uses the system tesseract binary when available. If missing, it returns ocr_unavailable_tesseract_not_found_or_failed and still returns pixel evidence.\n- OCR install: MCP cannot prompt. Ask the user first; if they agree, call vision.install-ocr with { "confirm": true }. If automatic install is unavailable, follow the returned installUrl.\n- Final judgment: OCR and pixel diff are evidence. A vision-capable model must still inspect screenshots/diff artifacts and compare the rendered result to user intent.\n'
|
|
12311
|
+
};
|
|
12312
|
+
const cliDocTitles = {
|
|
12313
|
+
"api-use-cases": "CLI API Use Cases",
|
|
12314
|
+
"manual-api": "Webstudio API CLI Manual",
|
|
12315
|
+
"manual-llm": "Webstudio CLI Manual for LLMs",
|
|
12316
|
+
"manual-mcp": "Webstudio MCP Manual",
|
|
12317
|
+
"mcp-startup-epilogue": "mcp-startup-epilogue",
|
|
12318
|
+
"mcp-vision": "MCP Vision Verification"
|
|
12319
|
+
};
|
|
12320
|
+
const cliDocSections = {
|
|
12321
|
+
"api-use-cases": {},
|
|
12322
|
+
"manual-api": {
|
|
12323
|
+
safetyRules: [
|
|
12324
|
+
"Pass --json to API/discovery commands that support it. Do not add --json to top-level commands unless their help/schema documents it.",
|
|
12325
|
+
"Never pass a project id. Commands use configured project only.",
|
|
12326
|
+
"Read ids before writing. Do not invent ids for existing records.",
|
|
12327
|
+
"stdout is one JSON object. stderr is diagnostics.",
|
|
12328
|
+
"Prefer MCP semantic tools for detailed project edits. Use MCP apply-patch only when no semantic tool exists.",
|
|
12329
|
+
"For MCP apply-patch, read the latest version with MCP snapshot before writing.",
|
|
12330
|
+
"Reuse ids from MCP snapshot output when updating existing records.",
|
|
12331
|
+
"Generate new unique ids when adding records.",
|
|
12332
|
+
"If apply-patch reports a version conflict, read the latest build and regenerate the patch.",
|
|
12333
|
+
"Prefer semantic MCP read tools for discovery, then use MCP snapshot for exact patch paths."
|
|
12334
|
+
]
|
|
12335
|
+
},
|
|
12336
|
+
"manual-llm": {
|
|
12337
|
+
implementationProcess: [
|
|
12338
|
+
"Discover capabilities with webstudio man llm --json, webstudio schema api --json, and MCP meta.index or webstudio://project/tools.",
|
|
12339
|
+
"Inspect current project state with semantic reads such as list-pages, get-page-by-path, list-instances, inspect-instance, get-styles, list-assets, list-breakpoints, and snapshot only when needed.",
|
|
12340
|
+
"Mutate the Webstudio project with semantic MCP write tools first. Prefer append-instance, update-text, update-props, update-styles, upload-asset, create-page, and page/project settings tools over raw patches.",
|
|
12341
|
+
"Use apply-patch only when no semantic tool covers the required change, and only after reading the latest snapshot/version.",
|
|
12342
|
+
"For visual/design work, regenerate or preview the generated app, capture a screenshot, inspect it with vision, and iterate before final response.",
|
|
12343
|
+
"Report what changed and what verification ran."
|
|
12344
|
+
],
|
|
12345
|
+
visualDesignWorkflow: [
|
|
12346
|
+
"Read editable Webstudio structure first: pages, instances, props, styles, breakpoints, assets, and relevant text.",
|
|
12347
|
+
"Do not use generated route/component files as the source of truth for editable content.",
|
|
12348
|
+
"Make edits through Webstudio semantic commands/MCP tools so the result stays editable in Builder and survives the next webstudio build.",
|
|
12349
|
+
"Keep generated project files current, start preview, and capture the changed page with screenshot.",
|
|
12350
|
+
"Use screenshot.diff when a baseline exists and inspect screenshot/diff artifacts with vision before finishing.",
|
|
12351
|
+
"If vision or screenshot tooling is unavailable, state that explicitly and explain what fallback verification was used."
|
|
12352
|
+
],
|
|
12353
|
+
responsiveVerification: [
|
|
12354
|
+
"Read breakpoints with list-breakpoints before deciding responsive behavior.",
|
|
12355
|
+
"Apply responsive styles with existing Builder breakpoint ids; do not invent CSS media queries or breakpoint names when Webstudio breakpoint data exists.",
|
|
12356
|
+
"Pick screenshot viewport widths from the project breakpoints: include a desktop width, each defined max-width or min-width edge, and a narrow mobile width.",
|
|
12357
|
+
'Capture each viewport with screenshot, for example {"path":"/","output":"home-375.png","viewport":{"width":375,"height":812}} and {"path":"/","output":"home-1440.png","viewport":{"width":1440,"height":900}}.',
|
|
12358
|
+
"Inspect every viewport screenshot with vision before finishing, checking layout, overflow, hidden content, text wrapping, and breakpoint-specific style changes.",
|
|
12359
|
+
"If any viewport fails, update styles through semantic Webstudio tools and repeat screenshots for the affected breakpoints."
|
|
12360
|
+
],
|
|
12361
|
+
generatedFileGuardrails: [
|
|
12362
|
+
"Do not edit app/__generated__, generated route files, generated page files, generated CSS, or build output for normal Webstudio content/design requests.",
|
|
12363
|
+
"Do not replace generated page components with handcrafted app code unless the user explicitly asks for code-only export customization.",
|
|
12364
|
+
"Generated files are build artifacts and may be overwritten by webstudio build.",
|
|
12365
|
+
"If a task truly requires generated app customization, keep it outside app/__generated__ where possible and explain that it is not editable Webstudio content."
|
|
12366
|
+
],
|
|
12367
|
+
valuesVsBindings: [
|
|
12368
|
+
"Use direct value tools for fixed content. For visible text, use update-text with plain text. For static props such as aria-label, alt, id, class, href, or button labels stored as props, use update-props with the prop's direct type/value.",
|
|
12369
|
+
"Use bind-props only when the prop must stay dynamic: an expression, parameter, resource result, or action. Do not use bind-props just to set a fixed string.",
|
|
12370
|
+
'Direct prop string example: {"updates":[{"instanceId":"button-id","name":"aria-label","type":"string","value":"Open menu"}]}.',
|
|
12371
|
+
'Expression binding example: {"bindings":[{"instanceId":"link-id","name":"href","binding":{"type":"expression","value":"currentPost.url"}}]}.',
|
|
12372
|
+
'Page metadata fields such as title, description, language, redirect, status, and custom meta content are expression-backed strings. For fixed text, pass a JavaScript string literal expression with JSON quoting, for example JSON.stringify("Pricing | Acme") in code or "\\"Pricing | Acme\\"" in JSON. Never pass raw multi-word text such as "Pricing | Acme" as an expression.',
|
|
12373
|
+
'Page metadata update example: use update-page with {"pageId":"page-id","values":{"title":"\\"Pricing | Acme\\"","meta":{"description":"\\"Plans for teams\\""}}}.',
|
|
12374
|
+
'Resource URL, header, search-param, and body fields are also expression-backed. For a fixed URL, use a string literal expression such as "\\"https://api.example.com/items\\"".',
|
|
12375
|
+
'Resource update example: use update-resource with {"resourceId":"resource-id","values":{"url":"\\"https://api.example.com/items\\""}}.'
|
|
12376
|
+
],
|
|
12377
|
+
rules: [
|
|
12378
|
+
"Never guess ids for existing records. Read them first.",
|
|
12379
|
+
"Never use project ids from user input. Commands use the configured project.",
|
|
12380
|
+
"Use --refresh before a local-capable command when cached data may be stale.",
|
|
12381
|
+
"Pass --json only to commands whose help/schema documents it. Do not add --json to top-level commands such as sync unless supported.",
|
|
12382
|
+
"On VERSION_CONFLICT, read MCP snapshot again, regenerate the patch, then retry.",
|
|
12383
|
+
"Treat stdout JSON as the API contract and stderr as diagnostics.",
|
|
12384
|
+
"For visual/design work, verify the rendered result with vision before finishing.",
|
|
12385
|
+
"Do not edit generated files for normal Webstudio content/design requests.",
|
|
12386
|
+
"Use direct values for static strings and bindings only for dynamic expressions/resources/actions.",
|
|
12387
|
+
"For expression-backed fields that need fixed text, encode the fixed text as a quoted JavaScript string literal expression.",
|
|
12388
|
+
"Confirm destructive commands with --confirm only when user requested deletion/unpublish/replacement.",
|
|
12389
|
+
"Use webstudio schema api --json for machine-readable command metadata."
|
|
12390
|
+
]
|
|
12391
|
+
},
|
|
12392
|
+
"manual-mcp": {
|
|
12393
|
+
rules: [
|
|
12394
|
+
"stdout is reserved for MCP JSON-RPC while the server is running.",
|
|
12395
|
+
"Operate on the configured project only.",
|
|
12396
|
+
"Read ids before writing.",
|
|
12397
|
+
"Prefer semantic tools over apply-patch.",
|
|
12398
|
+
"Use status and refresh when cached namespaces may be stale.",
|
|
12399
|
+
"A mutation is durable only when meta.session.committed is true.",
|
|
12400
|
+
"For visual/design work, verify the rendered result with vision before finishing."
|
|
12401
|
+
]
|
|
12402
|
+
},
|
|
12403
|
+
"mcp-startup-epilogue": {},
|
|
12404
|
+
"mcp-vision": {}
|
|
12209
12405
|
};
|
|
12210
12406
|
const readCliDoc = (name2) => cliDocs[name2];
|
|
12407
|
+
const readCliDocTitle = (name2) => cliDocTitles[name2];
|
|
12408
|
+
const readCliDocSections = (name2) => cliDocSections[name2];
|
|
12211
12409
|
const mcpVisionMarkdown = readCliDoc("mcp-vision");
|
|
12212
12410
|
const getSection = (markdown, heading) => {
|
|
12213
12411
|
const lines = markdown.split(/\r?\n/);
|
|
@@ -12269,6 +12467,14 @@ const createRuntimeMutation = ({
|
|
|
12269
12467
|
invalidatesNamespaces,
|
|
12270
12468
|
noop: payload.length === 0
|
|
12271
12469
|
});
|
|
12470
|
+
const assetReplaceInput = z.object({
|
|
12471
|
+
fromAssetId: z.string(),
|
|
12472
|
+
toAssetId: z.string()
|
|
12473
|
+
});
|
|
12474
|
+
const assetDeleteInput = z.object({
|
|
12475
|
+
assetIdsOrPrefixes: z.array(z.string()).min(1),
|
|
12476
|
+
force: z.boolean().optional()
|
|
12477
|
+
});
|
|
12272
12478
|
const traverseAssetStyleValue = (value2, callback) => {
|
|
12273
12479
|
callback(value2);
|
|
12274
12480
|
if (value2.type === "tuple" || value2.type === "layers") {
|
|
@@ -12776,6 +12982,15 @@ const deleteAssets = (state, input2) => {
|
|
|
12776
12982
|
invalidatesNamespaces: ["assets"]
|
|
12777
12983
|
});
|
|
12778
12984
|
};
|
|
12985
|
+
const getExpressionErrors = (expression) => lintExpression({ expression }).filter((diagnostic) => diagnostic.severity === "error").map((diagnostic) => diagnostic.message);
|
|
12986
|
+
const getNamedExpressionErrors = (name2, expression) => {
|
|
12987
|
+
if (expression === void 0) {
|
|
12988
|
+
return [];
|
|
12989
|
+
}
|
|
12990
|
+
return getExpressionErrors(expression).map(
|
|
12991
|
+
(message) => `${name2}: ${message}`
|
|
12992
|
+
);
|
|
12993
|
+
};
|
|
12779
12994
|
const getRequiredDataSources = (state) => {
|
|
12780
12995
|
if (state.dataSources === void 0) {
|
|
12781
12996
|
return throwBuilderRuntimeError(
|
|
@@ -12857,6 +13072,24 @@ const listDataVariables = (state, input2 = {}) => serializeDataVariables({
|
|
|
12857
13072
|
dataSources: getRequiredDataSources(state),
|
|
12858
13073
|
scopeInstanceId: input2.scopeInstanceId
|
|
12859
13074
|
});
|
|
13075
|
+
const dataVariableValueInput = dataSourceVariableValue;
|
|
13076
|
+
const dataVariableCreateInput = z.object({
|
|
13077
|
+
dataSourceId: z.string().optional(),
|
|
13078
|
+
scopeInstanceId: z.string(),
|
|
13079
|
+
name: z.string().min(1),
|
|
13080
|
+
value: dataVariableValueInput
|
|
13081
|
+
});
|
|
13082
|
+
const dataVariableUpdateInput = z.object({
|
|
13083
|
+
dataSourceId: z.string(),
|
|
13084
|
+
values: z.object({
|
|
13085
|
+
scopeInstanceId: z.string().optional(),
|
|
13086
|
+
name: z.string().min(1).optional(),
|
|
13087
|
+
value: dataVariableValueInput.optional()
|
|
13088
|
+
})
|
|
13089
|
+
});
|
|
13090
|
+
const dataVariableDeleteInput = z.object({
|
|
13091
|
+
dataSourceId: z.string()
|
|
13092
|
+
});
|
|
12860
13093
|
const validateDataVariableNameWithSources = ({
|
|
12861
13094
|
dataSources,
|
|
12862
13095
|
name: name2,
|
|
@@ -13457,8 +13690,40 @@ const findResource = (resources, resourceId2) => {
|
|
|
13457
13690
|
}
|
|
13458
13691
|
}
|
|
13459
13692
|
};
|
|
13460
|
-
const
|
|
13461
|
-
|
|
13693
|
+
const addExpressionIssues$2 = (context, errors) => {
|
|
13694
|
+
for (const message of errors) {
|
|
13695
|
+
context.addIssue({
|
|
13696
|
+
code: z.ZodIssueCode.custom,
|
|
13697
|
+
message
|
|
13698
|
+
});
|
|
13699
|
+
}
|
|
13700
|
+
};
|
|
13701
|
+
const resourceFieldsInputBase = resource.omit({ id: true }).extend({ control: z.enum(["system", "graphql"]).optional() });
|
|
13702
|
+
const resourceFieldsInput = resourceFieldsInputBase.superRefine(
|
|
13703
|
+
(fields, context) => {
|
|
13704
|
+
addExpressionIssues$2(context, getResourceExpressionErrors(fields));
|
|
13705
|
+
}
|
|
13706
|
+
);
|
|
13707
|
+
const resourceFieldsUpdateInput = resourceFieldsInputBase.partial().superRefine((fields, context) => {
|
|
13708
|
+
addExpressionIssues$2(context, getResourceExpressionErrors(fields));
|
|
13709
|
+
});
|
|
13710
|
+
const resourceCreateInput = z.object({
|
|
13711
|
+
resourceId: z.string().optional(),
|
|
13712
|
+
resource: resourceFieldsInput,
|
|
13713
|
+
dataSourceId: z.string().optional(),
|
|
13714
|
+
scopeInstanceId: z.string().optional(),
|
|
13715
|
+
dataSourceName: z.string().optional()
|
|
13716
|
+
});
|
|
13717
|
+
const resourceUpdateInput = z.object({
|
|
13718
|
+
resourceId: z.string(),
|
|
13719
|
+
values: resourceFieldsUpdateInput,
|
|
13720
|
+
dataSourceName: z.string().optional(),
|
|
13721
|
+
scopeInstanceId: z.string().optional()
|
|
13722
|
+
});
|
|
13723
|
+
const resourceDeleteInput = z.object({
|
|
13724
|
+
resourceId: z.string(),
|
|
13725
|
+
force: z.boolean().optional()
|
|
13726
|
+
});
|
|
13462
13727
|
const createResourceValue = ({
|
|
13463
13728
|
id,
|
|
13464
13729
|
control,
|
|
@@ -13481,14 +13746,7 @@ const createResourceValue = ({
|
|
|
13481
13746
|
const getResourceExpressionErrors = (fields) => {
|
|
13482
13747
|
const errors = [];
|
|
13483
13748
|
const validate = (name2, expression) => {
|
|
13484
|
-
|
|
13485
|
-
return;
|
|
13486
|
-
}
|
|
13487
|
-
for (const diagnostic of lintExpression({ expression })) {
|
|
13488
|
-
if (diagnostic.severity === "error") {
|
|
13489
|
-
errors.push(`${name2}: ${diagnostic.message}`);
|
|
13490
|
-
}
|
|
13491
|
-
}
|
|
13749
|
+
errors.push(...getNamedExpressionErrors(name2, expression));
|
|
13492
13750
|
};
|
|
13493
13751
|
validate("url", fields.url);
|
|
13494
13752
|
validate("body", fields.body);
|
|
@@ -14369,7 +14627,7 @@ const createPageValue = ({
|
|
|
14369
14627
|
pageId: pageId2,
|
|
14370
14628
|
name: name2,
|
|
14371
14629
|
path: path2,
|
|
14372
|
-
title = name2,
|
|
14630
|
+
title = JSON.stringify(name2),
|
|
14373
14631
|
rootInstanceId,
|
|
14374
14632
|
meta = {}
|
|
14375
14633
|
}) => ({
|
|
@@ -14386,13 +14644,29 @@ const emptyStringRemovesMetaFields = /* @__PURE__ */ new Set([
|
|
|
14386
14644
|
"socialImageAssetId",
|
|
14387
14645
|
"socialImageUrl"
|
|
14388
14646
|
]);
|
|
14647
|
+
const pageMetaExpressionFields = [
|
|
14648
|
+
"description",
|
|
14649
|
+
"language",
|
|
14650
|
+
"redirect",
|
|
14651
|
+
"socialImageUrl",
|
|
14652
|
+
"status",
|
|
14653
|
+
"content"
|
|
14654
|
+
];
|
|
14389
14655
|
const normalizePageMetaValue = (name2, value2) => {
|
|
14390
14656
|
if (value2 === "" && emptyStringRemovesMetaFields.has(name2)) {
|
|
14391
14657
|
return void 0;
|
|
14392
14658
|
}
|
|
14393
14659
|
return value2;
|
|
14394
14660
|
};
|
|
14395
|
-
const
|
|
14661
|
+
const addExpressionIssues$1 = (context, errors) => {
|
|
14662
|
+
for (const message of errors) {
|
|
14663
|
+
context.addIssue({
|
|
14664
|
+
code: z.ZodIssueCode.custom,
|
|
14665
|
+
message
|
|
14666
|
+
});
|
|
14667
|
+
}
|
|
14668
|
+
};
|
|
14669
|
+
const pageMetaInputBase = z.object({
|
|
14396
14670
|
description: z.string().optional(),
|
|
14397
14671
|
language: z.string().optional(),
|
|
14398
14672
|
redirect: z.string().optional(),
|
|
@@ -14405,13 +14679,72 @@ const pageMetaInput = z.object({
|
|
|
14405
14679
|
auth: pageAuth.optional(),
|
|
14406
14680
|
custom: z.array(z.object({ property: z.string(), content: z.string() })).optional()
|
|
14407
14681
|
});
|
|
14408
|
-
|
|
14682
|
+
const getPageExpressionErrors = (input2) => {
|
|
14683
|
+
const errors = [];
|
|
14684
|
+
errors.push(...getNamedExpressionErrors("title", input2.title));
|
|
14685
|
+
if (input2.meta !== void 0) {
|
|
14686
|
+
for (const name2 of pageMetaExpressionFields) {
|
|
14687
|
+
const expression = input2.meta[name2];
|
|
14688
|
+
if (expression === "" && emptyStringRemovesMetaFields.has(name2)) {
|
|
14689
|
+
continue;
|
|
14690
|
+
}
|
|
14691
|
+
errors.push(...getNamedExpressionErrors(`meta.${name2}`, expression));
|
|
14692
|
+
}
|
|
14693
|
+
for (const [index, customMeta] of (input2.meta.custom ?? []).entries()) {
|
|
14694
|
+
errors.push(
|
|
14695
|
+
...getNamedExpressionErrors(
|
|
14696
|
+
`meta.custom.${index}.content`,
|
|
14697
|
+
customMeta.content
|
|
14698
|
+
)
|
|
14699
|
+
);
|
|
14700
|
+
}
|
|
14701
|
+
}
|
|
14702
|
+
return errors;
|
|
14703
|
+
};
|
|
14704
|
+
const pageMetaInput = pageMetaInputBase.superRefine((meta, context) => {
|
|
14705
|
+
addExpressionIssues$1(context, getPageExpressionErrors({ meta }));
|
|
14706
|
+
});
|
|
14707
|
+
const pageFieldsInput = z.object({
|
|
14409
14708
|
name: z.string().min(1).optional(),
|
|
14410
14709
|
path: z.string().optional(),
|
|
14411
14710
|
title: z.string().optional(),
|
|
14412
14711
|
parentFolderId: z.string().optional(),
|
|
14712
|
+
meta: pageMetaInputBase.optional()
|
|
14713
|
+
}).superRefine((fields, context) => {
|
|
14714
|
+
addExpressionIssues$1(context, getPageExpressionErrors(fields));
|
|
14715
|
+
});
|
|
14716
|
+
const pageCreateInput = z.object({
|
|
14717
|
+
pageId: z.string().optional(),
|
|
14718
|
+
name: z.string().min(1),
|
|
14719
|
+
path: z.string(),
|
|
14720
|
+
title: z.string().optional(),
|
|
14721
|
+
parentFolderId: z.string().optional(),
|
|
14413
14722
|
meta: pageMetaInput.optional()
|
|
14414
14723
|
});
|
|
14724
|
+
const pageUpdateInput = z.object({
|
|
14725
|
+
pageId: z.string(),
|
|
14726
|
+
values: pageFieldsInput
|
|
14727
|
+
});
|
|
14728
|
+
const pageDeleteInput = z.object({
|
|
14729
|
+
pageId: z.string()
|
|
14730
|
+
});
|
|
14731
|
+
const folderCreateInput = z.object({
|
|
14732
|
+
folderId: z.string().optional(),
|
|
14733
|
+
name: z.string().min(1),
|
|
14734
|
+
slug: z.string(),
|
|
14735
|
+
parentFolderId: z.string().optional()
|
|
14736
|
+
});
|
|
14737
|
+
const folderUpdateInput = z.object({
|
|
14738
|
+
folderId: z.string(),
|
|
14739
|
+
values: z.object({
|
|
14740
|
+
name: z.string().min(1).optional(),
|
|
14741
|
+
slug: z.string().optional(),
|
|
14742
|
+
parentFolderId: z.string().optional()
|
|
14743
|
+
})
|
|
14744
|
+
});
|
|
14745
|
+
const folderDeleteInput = z.object({
|
|
14746
|
+
folderId: z.string()
|
|
14747
|
+
});
|
|
14415
14748
|
const pageMetaToPatchValue = (meta) => {
|
|
14416
14749
|
const result = {};
|
|
14417
14750
|
for (const [name2, value2] of Object.entries(meta)) {
|
|
@@ -14516,6 +14849,10 @@ const createPage = (state, input2, context) => {
|
|
|
14516
14849
|
const pages2 = getRequiredPages(state);
|
|
14517
14850
|
const parentFolderId = input2.parentFolderId ?? pages2.rootFolderId;
|
|
14518
14851
|
const parentFolder = getFolderOrThrow(pages2, parentFolderId);
|
|
14852
|
+
const expressionErrors = getPageExpressionErrors(input2);
|
|
14853
|
+
if (expressionErrors.length > 0) {
|
|
14854
|
+
return throwBuilderRuntimeError("BAD_REQUEST", expressionErrors.join("\n"));
|
|
14855
|
+
}
|
|
14519
14856
|
const pageId2 = input2.pageId ?? context.createId();
|
|
14520
14857
|
if (pages2.pages.has(pageId2)) {
|
|
14521
14858
|
return throwBuilderRuntimeError("CONFLICT", "Page id already exists");
|
|
@@ -14558,6 +14895,10 @@ const updatePage = (state, input2) => {
|
|
|
14558
14895
|
if (page2 === void 0) {
|
|
14559
14896
|
return throwBuilderRuntimeError("NOT_FOUND", "Page not found");
|
|
14560
14897
|
}
|
|
14898
|
+
const expressionErrors = getPageExpressionErrors(input2.values);
|
|
14899
|
+
if (expressionErrors.length > 0) {
|
|
14900
|
+
return throwBuilderRuntimeError("BAD_REQUEST", expressionErrors.join("\n"));
|
|
14901
|
+
}
|
|
14561
14902
|
if ((input2.values.path !== void 0 || input2.values.parentFolderId !== void 0) && isPathAvailable({
|
|
14562
14903
|
pages: pages2,
|
|
14563
14904
|
path: input2.values.path ?? page2.path,
|
|
@@ -14843,7 +15184,25 @@ const createPropBindingFromInput = ({
|
|
|
14843
15184
|
type: binding.type,
|
|
14844
15185
|
value: binding.value
|
|
14845
15186
|
});
|
|
14846
|
-
|
|
15187
|
+
const getPropValueErrors = ({
|
|
15188
|
+
type: type2,
|
|
15189
|
+
value: value2
|
|
15190
|
+
}) => {
|
|
15191
|
+
if (type2 !== "expression") {
|
|
15192
|
+
return [];
|
|
15193
|
+
}
|
|
15194
|
+
return getExpressionErrors(String(value2));
|
|
15195
|
+
};
|
|
15196
|
+
const addExpressionIssues = (context, errors, path2 = []) => {
|
|
15197
|
+
for (const message of errors) {
|
|
15198
|
+
context.addIssue({
|
|
15199
|
+
code: z.ZodIssueCode.custom,
|
|
15200
|
+
message,
|
|
15201
|
+
path: path2
|
|
15202
|
+
});
|
|
15203
|
+
}
|
|
15204
|
+
};
|
|
15205
|
+
const propValueInput = z.object({
|
|
14847
15206
|
propId: z.string().optional(),
|
|
14848
15207
|
instanceId: z.string(),
|
|
14849
15208
|
name: z.string(),
|
|
@@ -14863,8 +15222,10 @@ z.object({
|
|
|
14863
15222
|
]),
|
|
14864
15223
|
value: z.unknown(),
|
|
14865
15224
|
required: z.boolean().optional()
|
|
15225
|
+
}).superRefine((value2, context) => {
|
|
15226
|
+
addExpressionIssues(context, getPropValueErrors(value2), ["value"]);
|
|
14866
15227
|
});
|
|
14867
|
-
z.object({
|
|
15228
|
+
const propBindingInput = z.object({
|
|
14868
15229
|
propId: z.string().optional(),
|
|
14869
15230
|
instanceId: z.string(),
|
|
14870
15231
|
name: z.string(),
|
|
@@ -14883,16 +15244,25 @@ z.object({
|
|
|
14883
15244
|
)
|
|
14884
15245
|
})
|
|
14885
15246
|
])
|
|
15247
|
+
}).superRefine((value2, context) => {
|
|
15248
|
+
addExpressionIssues(
|
|
15249
|
+
context,
|
|
15250
|
+
getPropValueErrors({
|
|
15251
|
+
type: value2.binding.type,
|
|
15252
|
+
value: value2.binding.value
|
|
15253
|
+
}),
|
|
15254
|
+
["binding", "value"]
|
|
15255
|
+
);
|
|
15256
|
+
});
|
|
15257
|
+
const propUpdatesInput = z.object({
|
|
15258
|
+
updates: z.array(propValueInput).min(1)
|
|
15259
|
+
});
|
|
15260
|
+
const propBindingsInput = z.object({
|
|
15261
|
+
bindings: z.array(propBindingInput).min(1)
|
|
15262
|
+
});
|
|
15263
|
+
const propDeletionsInput = z.object({
|
|
15264
|
+
deletions: z.array(z.object({ instanceId: z.string(), name: z.string() })).min(1)
|
|
14886
15265
|
});
|
|
14887
|
-
const getPropValueErrors = ({
|
|
14888
|
-
type: type2,
|
|
14889
|
-
value: value2
|
|
14890
|
-
}) => {
|
|
14891
|
-
if (type2 !== "expression") {
|
|
14892
|
-
return [];
|
|
14893
|
-
}
|
|
14894
|
-
return lintExpression({ expression: String(value2) }).filter((diagnostic) => diagnostic.severity === "error").map((diagnostic) => diagnostic.message);
|
|
14895
|
-
};
|
|
14896
15266
|
const createMissingId = () => {
|
|
14897
15267
|
throw new Error("createId is required when propId is not provided.");
|
|
14898
15268
|
};
|
|
@@ -15345,6 +15715,44 @@ const createStyleClonePayload = ({
|
|
|
15345
15715
|
(change) => change.patches.length === 0 ? [] : [change]
|
|
15346
15716
|
);
|
|
15347
15717
|
};
|
|
15718
|
+
const insertIndexInput = z.number().int().nonnegative();
|
|
15719
|
+
const appendInstancesInput = z.object({
|
|
15720
|
+
parentInstanceId: z.string(),
|
|
15721
|
+
mode: z.enum(["append", "prepend", "replace"]).optional(),
|
|
15722
|
+
insertIndex: insertIndexInput.optional(),
|
|
15723
|
+
children: z.array(
|
|
15724
|
+
z.object({
|
|
15725
|
+
instanceId: z.string().optional(),
|
|
15726
|
+
component: z.string().optional(),
|
|
15727
|
+
tag: z.string(),
|
|
15728
|
+
label: z.string().optional(),
|
|
15729
|
+
text: z.string().optional()
|
|
15730
|
+
})
|
|
15731
|
+
).min(1)
|
|
15732
|
+
});
|
|
15733
|
+
const moveInstancesInput = z.object({
|
|
15734
|
+
moves: z.array(
|
|
15735
|
+
z.object({
|
|
15736
|
+
instanceId: z.string(),
|
|
15737
|
+
parentInstanceId: z.string(),
|
|
15738
|
+
insertIndex: insertIndexInput.optional()
|
|
15739
|
+
})
|
|
15740
|
+
).min(1)
|
|
15741
|
+
});
|
|
15742
|
+
const cloneInstanceInput = z.object({
|
|
15743
|
+
sourceInstanceId: z.string(),
|
|
15744
|
+
targetParentInstanceId: z.string().optional(),
|
|
15745
|
+
insertIndex: insertIndexInput.optional()
|
|
15746
|
+
});
|
|
15747
|
+
const deleteInstancesInput = z.object({
|
|
15748
|
+
instanceIds: z.array(z.string()).min(1)
|
|
15749
|
+
});
|
|
15750
|
+
const updateTextInstanceInput = z.object({
|
|
15751
|
+
instanceId: z.string(),
|
|
15752
|
+
childIndex: z.number().int().nonnegative(),
|
|
15753
|
+
text: z.string(),
|
|
15754
|
+
mode: z.enum(["text", "expression"]).optional()
|
|
15755
|
+
});
|
|
15348
15756
|
const getRequiredInstances = (state) => {
|
|
15349
15757
|
if (state.instances === void 0) {
|
|
15350
15758
|
return throwBuilderRuntimeError(
|
|
@@ -16093,7 +16501,7 @@ const getTextContentErrors = ({
|
|
|
16093
16501
|
if (type2 === "text") {
|
|
16094
16502
|
return [];
|
|
16095
16503
|
}
|
|
16096
|
-
return
|
|
16504
|
+
return getExpressionErrors(value2);
|
|
16097
16505
|
};
|
|
16098
16506
|
const createTextContentUpdatePayload = ({
|
|
16099
16507
|
instanceId: instanceId2,
|
|
@@ -17275,6 +17683,20 @@ const insertWebstudioFragmentCopy = ({
|
|
|
17275
17683
|
}
|
|
17276
17684
|
return newDataIds;
|
|
17277
17685
|
};
|
|
17686
|
+
const pageDuplicateInput = z.object({
|
|
17687
|
+
projectId: z.string(),
|
|
17688
|
+
pageId: z.string(),
|
|
17689
|
+
parentFolderId: z.string().optional(),
|
|
17690
|
+
name: z.string().min(1).optional(),
|
|
17691
|
+
path: z.string().optional()
|
|
17692
|
+
});
|
|
17693
|
+
const pageTemplateCreatePageInput = z.object({
|
|
17694
|
+
projectId: z.string(),
|
|
17695
|
+
templateId: z.string(),
|
|
17696
|
+
parentFolderId: z.string().optional(),
|
|
17697
|
+
name: z.string().min(1),
|
|
17698
|
+
path: z.string()
|
|
17699
|
+
});
|
|
17278
17700
|
const contentModePageMetaFields = /* @__PURE__ */ new Set([
|
|
17279
17701
|
"description",
|
|
17280
17702
|
"title",
|
|
@@ -17772,7 +18194,7 @@ const getRequiredBreakpoints = (state) => {
|
|
|
17772
18194
|
}
|
|
17773
18195
|
return state.breakpoints;
|
|
17774
18196
|
};
|
|
17775
|
-
z.object({
|
|
18197
|
+
const projectSettingsUpdateInput = z.object({
|
|
17776
18198
|
meta: z.record(z.unknown()).optional(),
|
|
17777
18199
|
compiler: z.record(z.unknown()).optional()
|
|
17778
18200
|
});
|
|
@@ -17878,16 +18300,24 @@ const listRedirects = (state) => ({
|
|
|
17878
18300
|
redirects: getRequiredPages(state).redirects ?? []
|
|
17879
18301
|
});
|
|
17880
18302
|
const redirectStatusInput = z.enum(["301", "302"]);
|
|
17881
|
-
z.object({
|
|
18303
|
+
const redirectFieldsInput = z.object({
|
|
17882
18304
|
old: z.string(),
|
|
17883
18305
|
new: z.string(),
|
|
17884
18306
|
status: redirectStatusInput.optional()
|
|
17885
18307
|
});
|
|
17886
|
-
z.object({
|
|
18308
|
+
const redirectUpdateFieldsInput = z.object({
|
|
17887
18309
|
old: z.string().optional(),
|
|
17888
18310
|
new: z.string().optional(),
|
|
17889
18311
|
status: redirectStatusInput.nullable().optional()
|
|
17890
18312
|
});
|
|
18313
|
+
const redirectCreateInput = redirectFieldsInput;
|
|
18314
|
+
const redirectUpdateInput = z.object({
|
|
18315
|
+
old: z.string(),
|
|
18316
|
+
values: redirectUpdateFieldsInput
|
|
18317
|
+
});
|
|
18318
|
+
const redirectDeleteInput = z.object({
|
|
18319
|
+
old: z.string()
|
|
18320
|
+
});
|
|
17891
18321
|
const findRedirectIndex = (redirects, oldPath) => redirects.findIndex((redirect) => redirect.old === oldPath);
|
|
17892
18322
|
const parseRedirect = (input2) => {
|
|
17893
18323
|
const result = pageRedirect.safeParse(input2);
|
|
@@ -17979,19 +18409,27 @@ const deleteRedirect = (state, input2) => {
|
|
|
17979
18409
|
const listBreakpoints = (state) => ({
|
|
17980
18410
|
breakpoints: Array.from(getRequiredBreakpoints(state).values())
|
|
17981
18411
|
});
|
|
17982
|
-
z.object({
|
|
18412
|
+
const breakpointFieldsInput = z.object({
|
|
17983
18413
|
id: z.string(),
|
|
17984
18414
|
label: z.string(),
|
|
17985
18415
|
minWidth: z.number().optional(),
|
|
17986
18416
|
maxWidth: z.number().optional(),
|
|
17987
18417
|
condition: z.string().optional()
|
|
17988
18418
|
});
|
|
17989
|
-
z.object({
|
|
18419
|
+
const breakpointUpdateFieldsInput = z.object({
|
|
17990
18420
|
label: z.string().optional(),
|
|
17991
18421
|
minWidth: z.number().nullable().optional(),
|
|
17992
18422
|
maxWidth: z.number().nullable().optional(),
|
|
17993
18423
|
condition: z.string().nullable().optional()
|
|
17994
18424
|
});
|
|
18425
|
+
const breakpointCreateInput = breakpointFieldsInput;
|
|
18426
|
+
const breakpointUpdateInput = z.object({
|
|
18427
|
+
breakpointId: z.string(),
|
|
18428
|
+
values: breakpointUpdateFieldsInput
|
|
18429
|
+
});
|
|
18430
|
+
const breakpointDeleteInput = z.object({
|
|
18431
|
+
breakpointId: z.string()
|
|
18432
|
+
});
|
|
17995
18433
|
const parseBreakpoint = (input2) => {
|
|
17996
18434
|
const result = breakpoint.safeParse(input2);
|
|
17997
18435
|
if (result.success === false) {
|
|
@@ -28896,7 +29334,7 @@ const withDefaultBreakpoint = (input2, breakpoint2) => ({
|
|
|
28896
29334
|
...input2,
|
|
28897
29335
|
breakpoint: input2.breakpoint ?? breakpoint2
|
|
28898
29336
|
});
|
|
28899
|
-
z.object({
|
|
29337
|
+
const styleUpdateInput = z.object({
|
|
28900
29338
|
instanceId: z.string(),
|
|
28901
29339
|
property: z.string(),
|
|
28902
29340
|
value: z.unknown(),
|
|
@@ -28905,13 +29343,30 @@ z.object({
|
|
|
28905
29343
|
listed: z.boolean().optional(),
|
|
28906
29344
|
createLocalIfMissing: z.boolean().optional()
|
|
28907
29345
|
});
|
|
28908
|
-
z.object({
|
|
29346
|
+
const styleDeleteInput = z.object({
|
|
28909
29347
|
instanceId: z.string(),
|
|
28910
29348
|
property: z.string(),
|
|
28911
29349
|
breakpoint: z.string().optional(),
|
|
28912
29350
|
state: z.string().optional()
|
|
28913
29351
|
});
|
|
28914
|
-
|
|
29352
|
+
const jsonArrayStringInput = (value2) => {
|
|
29353
|
+
if (typeof value2 !== "string") {
|
|
29354
|
+
return value2;
|
|
29355
|
+
}
|
|
29356
|
+
try {
|
|
29357
|
+
return JSON.parse(value2);
|
|
29358
|
+
} catch {
|
|
29359
|
+
return value2;
|
|
29360
|
+
}
|
|
29361
|
+
};
|
|
29362
|
+
const jsonArrayInput = (item) => z.preprocess(jsonArrayStringInput, z.array(item).min(1));
|
|
29363
|
+
const styleUpdateDeclarationsInput = z.object({
|
|
29364
|
+
updates: jsonArrayInput(styleUpdateInput)
|
|
29365
|
+
});
|
|
29366
|
+
const styleDeleteDeclarationsInput = z.object({
|
|
29367
|
+
deletions: jsonArrayInput(styleDeleteInput)
|
|
29368
|
+
});
|
|
29369
|
+
const styleReplaceInput = z.object({
|
|
28915
29370
|
property: z.string(),
|
|
28916
29371
|
fromValue: z.unknown(),
|
|
28917
29372
|
toValue: z.unknown(),
|
|
@@ -28970,7 +29425,19 @@ const getDefinedCssVariableNames = (styles) => {
|
|
|
28970
29425
|
}
|
|
28971
29426
|
return names;
|
|
28972
29427
|
};
|
|
28973
|
-
z.union([z.string(), styleValue]);
|
|
29428
|
+
const cssVariableValueInput = z.union([z.string(), styleValue]);
|
|
29429
|
+
const cssVariableDefineInput = z.object({
|
|
29430
|
+
vars: z.record(cssVariableValueInput),
|
|
29431
|
+
overwrite: z.boolean().optional()
|
|
29432
|
+
});
|
|
29433
|
+
const cssVariableDeleteInput = z.object({
|
|
29434
|
+
names: z.array(z.string()).min(1),
|
|
29435
|
+
force: z.boolean().optional()
|
|
29436
|
+
});
|
|
29437
|
+
const cssVariableRewriteRefsInput = z.object({
|
|
29438
|
+
map: z.record(z.string()),
|
|
29439
|
+
scopeRegex: z.string().optional()
|
|
29440
|
+
});
|
|
28974
29441
|
const validateCssVariableNameWithStyles = ({
|
|
28975
29442
|
name: name2,
|
|
28976
29443
|
styles,
|
|
@@ -29254,12 +29721,37 @@ const designTokenStyleInput = z.object({
|
|
|
29254
29721
|
breakpoint: z.string().optional(),
|
|
29255
29722
|
state: z.string().optional()
|
|
29256
29723
|
});
|
|
29257
|
-
z.object({
|
|
29724
|
+
const designTokenCreateInput = z.object({
|
|
29258
29725
|
tokenId: z.string().optional(),
|
|
29259
29726
|
name: z.string().min(1),
|
|
29260
29727
|
styles: z.record(z.unknown()).optional(),
|
|
29261
29728
|
declarations: z.array(designTokenStyleInput).optional()
|
|
29262
29729
|
});
|
|
29730
|
+
const designTokenCreateManyInput = z.object({
|
|
29731
|
+
tokens: jsonArrayInput(designTokenCreateInput)
|
|
29732
|
+
});
|
|
29733
|
+
const designTokenStyleUpdatesInput = z.object({
|
|
29734
|
+
designTokenId: z.string(),
|
|
29735
|
+
updates: jsonArrayInput(designTokenStyleInput)
|
|
29736
|
+
});
|
|
29737
|
+
const designTokenStyleDeletionsInput = z.object({
|
|
29738
|
+
designTokenId: z.string(),
|
|
29739
|
+
deletions: jsonArrayInput(styleDeleteInput.omit({ instanceId: true }))
|
|
29740
|
+
});
|
|
29741
|
+
const designTokenAttachInput = z.object({
|
|
29742
|
+
designTokenId: z.string(),
|
|
29743
|
+
instanceIds: z.array(z.string()).min(1),
|
|
29744
|
+
position: z.enum(["before-local", "after-local"]).optional()
|
|
29745
|
+
});
|
|
29746
|
+
const designTokenDetachInput = z.object({
|
|
29747
|
+
designTokenId: z.string(),
|
|
29748
|
+
instanceIds: z.array(z.string()).min(1)
|
|
29749
|
+
});
|
|
29750
|
+
const designTokenExtractInput = z.object({
|
|
29751
|
+
instanceIds: z.array(z.string()).min(1),
|
|
29752
|
+
name: z.string().min(1),
|
|
29753
|
+
removeLocalProps: z.array(z.string()).optional()
|
|
29754
|
+
});
|
|
29263
29755
|
const createTokenStyleSource = ({
|
|
29264
29756
|
id,
|
|
29265
29757
|
name: name2,
|
|
@@ -30314,15 +30806,11 @@ const builderRuntimeOperations = [
|
|
|
30314
30806
|
),
|
|
30315
30807
|
runtimeOperation(
|
|
30316
30808
|
"pages.create",
|
|
30317
|
-
({ state, input: input2, context }) => createPage(
|
|
30318
|
-
state,
|
|
30319
|
-
input2,
|
|
30320
|
-
context
|
|
30321
|
-
)
|
|
30809
|
+
({ state, input: input2, context }) => createPage(state, pageCreateInput.parse(input2), context)
|
|
30322
30810
|
),
|
|
30323
30811
|
runtimeOperation(
|
|
30324
30812
|
"pages.update",
|
|
30325
|
-
({ state, input: input2 }) => updatePage(state, input2)
|
|
30813
|
+
({ state, input: input2 }) => updatePage(state, pageUpdateInput.parse(input2))
|
|
30326
30814
|
),
|
|
30327
30815
|
runtimeOperation(
|
|
30328
30816
|
"projectSettings.get",
|
|
@@ -30332,7 +30820,7 @@ const builderRuntimeOperations = [
|
|
|
30332
30820
|
"projectSettings.update",
|
|
30333
30821
|
({ state, input: input2 }) => updateProjectSettings(
|
|
30334
30822
|
state,
|
|
30335
|
-
input2
|
|
30823
|
+
projectSettingsUpdateInput.parse(input2)
|
|
30336
30824
|
)
|
|
30337
30825
|
),
|
|
30338
30826
|
runtimeOperation(
|
|
@@ -30343,21 +30831,21 @@ const builderRuntimeOperations = [
|
|
|
30343
30831
|
"redirects.create",
|
|
30344
30832
|
({ state, input: input2 }) => createRedirect(
|
|
30345
30833
|
state,
|
|
30346
|
-
input2
|
|
30834
|
+
redirectCreateInput.parse(input2)
|
|
30347
30835
|
)
|
|
30348
30836
|
),
|
|
30349
30837
|
runtimeOperation(
|
|
30350
30838
|
"redirects.update",
|
|
30351
30839
|
({ state, input: input2 }) => updateRedirect(
|
|
30352
30840
|
state,
|
|
30353
|
-
input2
|
|
30841
|
+
redirectUpdateInput.parse(input2)
|
|
30354
30842
|
)
|
|
30355
30843
|
),
|
|
30356
30844
|
runtimeOperation(
|
|
30357
30845
|
"redirects.delete",
|
|
30358
30846
|
({ state, input: input2 }) => deleteRedirect(
|
|
30359
30847
|
state,
|
|
30360
|
-
input2
|
|
30848
|
+
redirectDeleteInput.parse(input2)
|
|
30361
30849
|
)
|
|
30362
30850
|
),
|
|
30363
30851
|
runtimeOperation(
|
|
@@ -30368,32 +30856,32 @@ const builderRuntimeOperations = [
|
|
|
30368
30856
|
"breakpoints.create",
|
|
30369
30857
|
({ state, input: input2 }) => createBreakpoint(
|
|
30370
30858
|
state,
|
|
30371
|
-
input2
|
|
30859
|
+
breakpointCreateInput.parse(input2)
|
|
30372
30860
|
)
|
|
30373
30861
|
),
|
|
30374
30862
|
runtimeOperation(
|
|
30375
30863
|
"breakpoints.update",
|
|
30376
30864
|
({ state, input: input2 }) => updateBreakpoint(
|
|
30377
30865
|
state,
|
|
30378
|
-
input2
|
|
30866
|
+
breakpointUpdateInput.parse(input2)
|
|
30379
30867
|
)
|
|
30380
30868
|
),
|
|
30381
30869
|
runtimeOperation(
|
|
30382
30870
|
"breakpoints.delete",
|
|
30383
30871
|
({ state, input: input2 }) => deleteBreakpoint(
|
|
30384
30872
|
state,
|
|
30385
|
-
input2
|
|
30873
|
+
breakpointDeleteInput.parse(input2)
|
|
30386
30874
|
)
|
|
30387
30875
|
),
|
|
30388
30876
|
runtimeOperation(
|
|
30389
30877
|
"pages.delete",
|
|
30390
|
-
({ state, input: input2 }) => deletePage(state, input2)
|
|
30878
|
+
({ state, input: input2 }) => deletePage(state, pageDeleteInput.parse(input2))
|
|
30391
30879
|
),
|
|
30392
30880
|
runtimeOperation(
|
|
30393
30881
|
"pages.duplicate",
|
|
30394
30882
|
({ state, input: input2, context }) => duplicatePage(
|
|
30395
30883
|
state,
|
|
30396
|
-
input2,
|
|
30884
|
+
pageDuplicateInput.parse(input2),
|
|
30397
30885
|
context
|
|
30398
30886
|
)
|
|
30399
30887
|
),
|
|
@@ -30405,7 +30893,7 @@ const builderRuntimeOperations = [
|
|
|
30405
30893
|
"pageTemplates.createPage",
|
|
30406
30894
|
({ state, input: input2, context }) => createPageFromTemplate(
|
|
30407
30895
|
state,
|
|
30408
|
-
input2,
|
|
30896
|
+
pageTemplateCreatePageInput.parse(input2),
|
|
30409
30897
|
context
|
|
30410
30898
|
)
|
|
30411
30899
|
),
|
|
@@ -30415,19 +30903,15 @@ const builderRuntimeOperations = [
|
|
|
30415
30903
|
),
|
|
30416
30904
|
runtimeOperation(
|
|
30417
30905
|
"folders.create",
|
|
30418
|
-
({ state, input: input2, context }) => createFolder(
|
|
30419
|
-
state,
|
|
30420
|
-
input2,
|
|
30421
|
-
context
|
|
30422
|
-
)
|
|
30906
|
+
({ state, input: input2, context }) => createFolder(state, folderCreateInput.parse(input2), context)
|
|
30423
30907
|
),
|
|
30424
30908
|
runtimeOperation(
|
|
30425
30909
|
"folders.update",
|
|
30426
|
-
({ state, input: input2 }) => updateFolder(state, input2)
|
|
30910
|
+
({ state, input: input2 }) => updateFolder(state, folderUpdateInput.parse(input2))
|
|
30427
30911
|
),
|
|
30428
30912
|
runtimeOperation(
|
|
30429
30913
|
"folders.delete",
|
|
30430
|
-
({ state, input: input2 }) => deleteFolder(state, input2)
|
|
30914
|
+
({ state, input: input2 }) => deleteFolder(state, folderDeleteInput.parse(input2))
|
|
30431
30915
|
),
|
|
30432
30916
|
runtimeOperation(
|
|
30433
30917
|
"instances.list",
|
|
@@ -30447,22 +30931,19 @@ const builderRuntimeOperations = [
|
|
|
30447
30931
|
"instances.append",
|
|
30448
30932
|
({ state, input: input2, context }) => appendInstances(
|
|
30449
30933
|
state,
|
|
30450
|
-
input2,
|
|
30934
|
+
appendInstancesInput.parse(input2),
|
|
30451
30935
|
context
|
|
30452
30936
|
)
|
|
30453
30937
|
),
|
|
30454
30938
|
runtimeOperation(
|
|
30455
30939
|
"instances.move",
|
|
30456
|
-
({ state, input: input2 }) => moveInstances(
|
|
30457
|
-
state,
|
|
30458
|
-
input2
|
|
30459
|
-
)
|
|
30940
|
+
({ state, input: input2 }) => moveInstances(state, moveInstancesInput.parse(input2))
|
|
30460
30941
|
),
|
|
30461
30942
|
runtimeOperation(
|
|
30462
30943
|
"instances.clone",
|
|
30463
30944
|
({ state, input: input2, context }) => cloneInstance(
|
|
30464
30945
|
state,
|
|
30465
|
-
input2,
|
|
30946
|
+
cloneInstanceInput.parse(input2),
|
|
30466
30947
|
context
|
|
30467
30948
|
)
|
|
30468
30949
|
),
|
|
@@ -30470,28 +30951,20 @@ const builderRuntimeOperations = [
|
|
|
30470
30951
|
"instances.delete",
|
|
30471
30952
|
({ state, input: input2 }) => deleteInstances(
|
|
30472
30953
|
state,
|
|
30473
|
-
input2
|
|
30954
|
+
deleteInstancesInput.parse(input2)
|
|
30474
30955
|
)
|
|
30475
30956
|
),
|
|
30476
30957
|
runtimeOperation(
|
|
30477
30958
|
"instances.updateProps",
|
|
30478
|
-
({ state, input: input2, context }) => updateProps(
|
|
30479
|
-
state,
|
|
30480
|
-
input2,
|
|
30481
|
-
context
|
|
30482
|
-
)
|
|
30959
|
+
({ state, input: input2, context }) => updateProps(state, propUpdatesInput.parse(input2), context)
|
|
30483
30960
|
),
|
|
30484
30961
|
runtimeOperation(
|
|
30485
30962
|
"instances.deleteProps",
|
|
30486
|
-
({ state, input: input2 }) => deleteProps(state, input2)
|
|
30963
|
+
({ state, input: input2 }) => deleteProps(state, propDeletionsInput.parse(input2))
|
|
30487
30964
|
),
|
|
30488
30965
|
runtimeOperation(
|
|
30489
30966
|
"instances.bindProps",
|
|
30490
|
-
({ state, input: input2, context }) => bindProps(
|
|
30491
|
-
state,
|
|
30492
|
-
input2,
|
|
30493
|
-
context
|
|
30494
|
-
)
|
|
30967
|
+
({ state, input: input2, context }) => bindProps(state, propBindingsInput.parse(input2), context)
|
|
30495
30968
|
),
|
|
30496
30969
|
runtimeOperation(
|
|
30497
30970
|
"instances.listTexts",
|
|
@@ -30504,7 +30977,7 @@ const builderRuntimeOperations = [
|
|
|
30504
30977
|
"instances.updateText",
|
|
30505
30978
|
({ state, input: input2 }) => updateTextInstance(
|
|
30506
30979
|
state,
|
|
30507
|
-
input2
|
|
30980
|
+
updateTextInstanceInput.parse(input2)
|
|
30508
30981
|
)
|
|
30509
30982
|
),
|
|
30510
30983
|
runtimeOperation(
|
|
@@ -30518,7 +30991,7 @@ const builderRuntimeOperations = [
|
|
|
30518
30991
|
"styles.updateDeclarations",
|
|
30519
30992
|
({ state, input: input2, context }) => updateStyleDeclarations(
|
|
30520
30993
|
state,
|
|
30521
|
-
input2,
|
|
30994
|
+
styleUpdateDeclarationsInput.parse(input2),
|
|
30522
30995
|
context
|
|
30523
30996
|
)
|
|
30524
30997
|
),
|
|
@@ -30526,15 +30999,12 @@ const builderRuntimeOperations = [
|
|
|
30526
30999
|
"styles.deleteDeclarations",
|
|
30527
31000
|
({ state, input: input2 }) => deleteStyleDeclarations(
|
|
30528
31001
|
state,
|
|
30529
|
-
input2
|
|
31002
|
+
styleDeleteDeclarationsInput.parse(input2)
|
|
30530
31003
|
)
|
|
30531
31004
|
),
|
|
30532
31005
|
runtimeOperation(
|
|
30533
31006
|
"styles.replaceValues",
|
|
30534
|
-
({ state, input: input2 }) => replaceStyleValues(
|
|
30535
|
-
state,
|
|
30536
|
-
input2
|
|
30537
|
-
)
|
|
31007
|
+
({ state, input: input2 }) => replaceStyleValues(state, styleReplaceInput.parse(input2))
|
|
30538
31008
|
),
|
|
30539
31009
|
runtimeOperation(
|
|
30540
31010
|
"designTokens.list",
|
|
@@ -30547,7 +31017,7 @@ const builderRuntimeOperations = [
|
|
|
30547
31017
|
"designTokens.create",
|
|
30548
31018
|
({ state, input: input2, context }) => createDesignTokens(
|
|
30549
31019
|
state,
|
|
30550
|
-
input2,
|
|
31020
|
+
designTokenCreateManyInput.parse(input2),
|
|
30551
31021
|
context
|
|
30552
31022
|
)
|
|
30553
31023
|
),
|
|
@@ -30555,35 +31025,29 @@ const builderRuntimeOperations = [
|
|
|
30555
31025
|
"designTokens.updateStyles",
|
|
30556
31026
|
({ state, input: input2 }) => updateDesignTokenStyles(
|
|
30557
31027
|
state,
|
|
30558
|
-
input2
|
|
31028
|
+
designTokenStyleUpdatesInput.parse(input2)
|
|
30559
31029
|
)
|
|
30560
31030
|
),
|
|
30561
31031
|
runtimeOperation(
|
|
30562
31032
|
"designTokens.deleteStyles",
|
|
30563
31033
|
({ state, input: input2 }) => deleteDesignTokenStyles(
|
|
30564
31034
|
state,
|
|
30565
|
-
input2
|
|
31035
|
+
designTokenStyleDeletionsInput.parse(input2)
|
|
30566
31036
|
)
|
|
30567
31037
|
),
|
|
30568
31038
|
runtimeOperation(
|
|
30569
31039
|
"designTokens.attach",
|
|
30570
|
-
({ state, input: input2 }) => attachDesignToken(
|
|
30571
|
-
state,
|
|
30572
|
-
input2
|
|
30573
|
-
)
|
|
31040
|
+
({ state, input: input2 }) => attachDesignToken(state, designTokenAttachInput.parse(input2))
|
|
30574
31041
|
),
|
|
30575
31042
|
runtimeOperation(
|
|
30576
31043
|
"designTokens.detach",
|
|
30577
|
-
({ state, input: input2 }) => detachDesignToken(
|
|
30578
|
-
state,
|
|
30579
|
-
input2
|
|
30580
|
-
)
|
|
31044
|
+
({ state, input: input2 }) => detachDesignToken(state, designTokenDetachInput.parse(input2))
|
|
30581
31045
|
),
|
|
30582
31046
|
runtimeOperation(
|
|
30583
31047
|
"designTokens.extract",
|
|
30584
31048
|
({ state, input: input2, context }) => extractDesignToken(
|
|
30585
31049
|
state,
|
|
30586
|
-
input2,
|
|
31050
|
+
designTokenExtractInput.parse(input2),
|
|
30587
31051
|
context
|
|
30588
31052
|
)
|
|
30589
31053
|
),
|
|
@@ -30598,22 +31062,19 @@ const builderRuntimeOperations = [
|
|
|
30598
31062
|
"cssVariables.define",
|
|
30599
31063
|
({ state, input: input2, context }) => defineCssVariables(
|
|
30600
31064
|
state,
|
|
30601
|
-
input2,
|
|
31065
|
+
cssVariableDefineInput.parse(input2),
|
|
30602
31066
|
context
|
|
30603
31067
|
)
|
|
30604
31068
|
),
|
|
30605
31069
|
runtimeOperation(
|
|
30606
31070
|
"cssVariables.delete",
|
|
30607
|
-
({ state, input: input2 }) => deleteCssVariables(
|
|
30608
|
-
state,
|
|
30609
|
-
input2
|
|
30610
|
-
)
|
|
31071
|
+
({ state, input: input2 }) => deleteCssVariables(state, cssVariableDeleteInput.parse(input2))
|
|
30611
31072
|
),
|
|
30612
31073
|
runtimeOperation(
|
|
30613
31074
|
"cssVariables.rewriteRefs",
|
|
30614
31075
|
({ state, input: input2 }) => rewriteCssVariableRefs(
|
|
30615
31076
|
state,
|
|
30616
|
-
input2
|
|
31077
|
+
cssVariableRewriteRefsInput.parse(input2)
|
|
30617
31078
|
)
|
|
30618
31079
|
),
|
|
30619
31080
|
runtimeOperation(
|
|
@@ -30627,23 +31088,17 @@ const builderRuntimeOperations = [
|
|
|
30627
31088
|
"variables.create",
|
|
30628
31089
|
({ state, input: input2, context }) => createDataVariable(
|
|
30629
31090
|
state,
|
|
30630
|
-
input2,
|
|
31091
|
+
dataVariableCreateInput.parse(input2),
|
|
30631
31092
|
context
|
|
30632
31093
|
)
|
|
30633
31094
|
),
|
|
30634
31095
|
runtimeOperation(
|
|
30635
31096
|
"variables.update",
|
|
30636
|
-
({ state, input: input2 }) => updateDataVariable(
|
|
30637
|
-
state,
|
|
30638
|
-
input2
|
|
30639
|
-
)
|
|
31097
|
+
({ state, input: input2 }) => updateDataVariable(state, dataVariableUpdateInput.parse(input2))
|
|
30640
31098
|
),
|
|
30641
31099
|
runtimeOperation(
|
|
30642
31100
|
"variables.delete",
|
|
30643
|
-
({ state, input: input2 }) => deleteDataVariable(
|
|
30644
|
-
state,
|
|
30645
|
-
input2
|
|
30646
|
-
)
|
|
31101
|
+
({ state, input: input2 }) => deleteDataVariable(state, dataVariableDeleteInput.parse(input2))
|
|
30647
31102
|
),
|
|
30648
31103
|
runtimeOperation(
|
|
30649
31104
|
"resources.list",
|
|
@@ -30651,25 +31106,15 @@ const builderRuntimeOperations = [
|
|
|
30651
31106
|
),
|
|
30652
31107
|
runtimeOperation(
|
|
30653
31108
|
"resources.create",
|
|
30654
|
-
({ state, input: input2, context }) => createResource(
|
|
30655
|
-
state,
|
|
30656
|
-
input2,
|
|
30657
|
-
context
|
|
30658
|
-
)
|
|
31109
|
+
({ state, input: input2, context }) => createResource(state, resourceCreateInput.parse(input2), context)
|
|
30659
31110
|
),
|
|
30660
31111
|
runtimeOperation(
|
|
30661
31112
|
"resources.update",
|
|
30662
|
-
({ state, input: input2 }) => updateResource(
|
|
30663
|
-
state,
|
|
30664
|
-
input2
|
|
30665
|
-
)
|
|
31113
|
+
({ state, input: input2 }) => updateResource(state, resourceUpdateInput.parse(input2))
|
|
30666
31114
|
),
|
|
30667
31115
|
runtimeOperation(
|
|
30668
31116
|
"resources.delete",
|
|
30669
|
-
({ state, input: input2 }) => deleteResource(
|
|
30670
|
-
state,
|
|
30671
|
-
input2
|
|
30672
|
-
)
|
|
31117
|
+
({ state, input: input2 }) => deleteResource(state, resourceDeleteInput.parse(input2))
|
|
30673
31118
|
),
|
|
30674
31119
|
runtimeOperation(
|
|
30675
31120
|
"assets.list",
|
|
@@ -30684,17 +31129,11 @@ const builderRuntimeOperations = [
|
|
|
30684
31129
|
),
|
|
30685
31130
|
runtimeOperation(
|
|
30686
31131
|
"assets.replace",
|
|
30687
|
-
({ state, input: input2 }) => replaceAsset(
|
|
30688
|
-
state,
|
|
30689
|
-
input2
|
|
30690
|
-
)
|
|
31132
|
+
({ state, input: input2 }) => replaceAsset(state, assetReplaceInput.parse(input2))
|
|
30691
31133
|
),
|
|
30692
31134
|
runtimeOperation(
|
|
30693
31135
|
"assets.delete",
|
|
30694
|
-
({ state, input: input2 }) => deleteAssets(
|
|
30695
|
-
state,
|
|
30696
|
-
input2
|
|
30697
|
-
)
|
|
31136
|
+
({ state, input: input2 }) => deleteAssets(state, assetDeleteInput.parse(input2))
|
|
30698
31137
|
)
|
|
30699
31138
|
];
|
|
30700
31139
|
const builderRuntimeOperationById = new Map(
|
|
@@ -34462,127 +34901,128 @@ const manualReplacements = {
|
|
|
34462
34901
|
const apiManual = renderMarkdownTemplate(apiManualMarkdown, manualReplacements);
|
|
34463
34902
|
const llmManual = renderMarkdownTemplate(llmManualMarkdown, manualReplacements);
|
|
34464
34903
|
const mcpManual = renderMarkdownTemplate(mcpManualMarkdown, manualReplacements);
|
|
34904
|
+
const apiDocSections = readCliDocSections("manual-api");
|
|
34905
|
+
const llmDocSections = readCliDocSections("manual-llm");
|
|
34906
|
+
const mcpDocSections = readCliDocSections("manual-mcp");
|
|
34907
|
+
const mergeDocSections = (topic, json, sections) => {
|
|
34908
|
+
for (const fieldName of Object.keys(sections)) {
|
|
34909
|
+
if (Object.hasOwn(json, fieldName)) {
|
|
34910
|
+
throw new Error(
|
|
34911
|
+
`Doc metadata field "${fieldName}" conflicts with ${topic} manual JSON`
|
|
34912
|
+
);
|
|
34913
|
+
}
|
|
34914
|
+
}
|
|
34915
|
+
return { ...json, ...sections };
|
|
34916
|
+
};
|
|
34465
34917
|
const topics = {
|
|
34466
34918
|
api: {
|
|
34467
34919
|
manual: apiManual,
|
|
34468
|
-
json:
|
|
34469
|
-
|
|
34470
|
-
|
|
34471
|
-
|
|
34472
|
-
"
|
|
34473
|
-
|
|
34474
|
-
|
|
34475
|
-
|
|
34476
|
-
|
|
34477
|
-
|
|
34478
|
-
|
|
34479
|
-
|
|
34480
|
-
|
|
34481
|
-
|
|
34482
|
-
|
|
34483
|
-
|
|
34484
|
-
|
|
34485
|
-
|
|
34486
|
-
|
|
34487
|
-
|
|
34488
|
-
|
|
34489
|
-
|
|
34490
|
-
|
|
34491
|
-
|
|
34492
|
-
|
|
34493
|
-
|
|
34494
|
-
|
|
34495
|
-
|
|
34496
|
-
|
|
34920
|
+
json: mergeDocSections(
|
|
34921
|
+
"api",
|
|
34922
|
+
{
|
|
34923
|
+
topic: "api",
|
|
34924
|
+
title: readCliDocTitle("manual-api"),
|
|
34925
|
+
workflows: [
|
|
34926
|
+
"webstudio init --link <api-share-link> --json",
|
|
34927
|
+
"webstudio permissions --json",
|
|
34928
|
+
"webstudio schema api --json",
|
|
34929
|
+
"webstudio publish deploy --target production --json",
|
|
34930
|
+
"webstudio domains list --json",
|
|
34931
|
+
"webstudio mcp"
|
|
34932
|
+
],
|
|
34933
|
+
taskRecipes,
|
|
34934
|
+
useCaseScenarios,
|
|
34935
|
+
knownGaps: knownCliGaps,
|
|
34936
|
+
topLevelCommands: topLevelCommandCatalog,
|
|
34937
|
+
apiCommandsByArea,
|
|
34938
|
+
mcpOnlyCommands: mcpOnlyCommandCatalog,
|
|
34939
|
+
inputFileShapes,
|
|
34940
|
+
mcpArgumentExamples,
|
|
34941
|
+
commands: commandCatalog,
|
|
34942
|
+
readCommands,
|
|
34943
|
+
writeCommands,
|
|
34944
|
+
mutationNamespaces: buildPatchNamespaces,
|
|
34945
|
+
sessionBehavior: {
|
|
34946
|
+
localReads: "Use compatible cached namespaces and fetch only missing or stale namespaces.",
|
|
34947
|
+
localMutations: "Build patches locally, commit with the cached build version, and update local state only after remote commit succeeds.",
|
|
34948
|
+
serverOnly: "Run remotely and invalidate/refetch namespaces declared by the public operation catalog.",
|
|
34949
|
+
refreshFlag: "Use --refresh to refresh required namespaces before local-capable commands.",
|
|
34950
|
+
metadata: "Successful command JSON includes meta.session with operationId, buildId, version, source, committed, compatibility, namespace metadata, and diagnostics."
|
|
34951
|
+
}
|
|
34497
34952
|
},
|
|
34498
|
-
|
|
34499
|
-
|
|
34500
|
-
"Never pass project ids; commands use the configured project.",
|
|
34501
|
-
"Read ids before writing.",
|
|
34502
|
-
"Prefer semantic MCP write tools over apply-patch.",
|
|
34503
|
-
"For MCP apply-patch, read the latest version with MCP snapshot before writing.",
|
|
34504
|
-
"Reuse ids from MCP snapshot output when updating existing records.",
|
|
34505
|
-
"Generate new unique ids when adding records.",
|
|
34506
|
-
"Regenerate the patch after a version conflict."
|
|
34507
|
-
]
|
|
34508
|
-
}
|
|
34953
|
+
apiDocSections
|
|
34954
|
+
)
|
|
34509
34955
|
},
|
|
34510
34956
|
llm: {
|
|
34511
34957
|
manual: llmManual,
|
|
34512
|
-
json:
|
|
34513
|
-
|
|
34514
|
-
|
|
34515
|
-
|
|
34516
|
-
|
|
34517
|
-
|
|
34518
|
-
|
|
34519
|
-
|
|
34520
|
-
|
|
34521
|
-
|
|
34522
|
-
|
|
34523
|
-
|
|
34524
|
-
|
|
34525
|
-
|
|
34526
|
-
|
|
34527
|
-
|
|
34528
|
-
|
|
34529
|
-
|
|
34530
|
-
|
|
34531
|
-
|
|
34532
|
-
|
|
34533
|
-
|
|
34534
|
-
|
|
34535
|
-
|
|
34536
|
-
|
|
34537
|
-
|
|
34538
|
-
|
|
34539
|
-
|
|
34540
|
-
|
|
34541
|
-
|
|
34542
|
-
|
|
34543
|
-
|
|
34544
|
-
|
|
34545
|
-
|
|
34546
|
-
|
|
34547
|
-
|
|
34548
|
-
|
|
34549
|
-
}
|
|
34958
|
+
json: mergeDocSections(
|
|
34959
|
+
"llm",
|
|
34960
|
+
{
|
|
34961
|
+
topic: "llm",
|
|
34962
|
+
title: readCliDocTitle("manual-llm"),
|
|
34963
|
+
discovery: [
|
|
34964
|
+
"webstudio schema api --json",
|
|
34965
|
+
"webstudio permissions --json",
|
|
34966
|
+
"webstudio mcp",
|
|
34967
|
+
"MCP tool: status",
|
|
34968
|
+
"MCP resource: webstudio://project/tools"
|
|
34969
|
+
],
|
|
34970
|
+
taskRecipes,
|
|
34971
|
+
useCaseScenarios,
|
|
34972
|
+
knownGaps: knownCliGaps,
|
|
34973
|
+
topLevelCommands: topLevelCommandCatalog,
|
|
34974
|
+
apiCommandsByArea,
|
|
34975
|
+
mcpOnlyCommands: mcpOnlyCommandCatalog,
|
|
34976
|
+
inputFileShapes,
|
|
34977
|
+
mcpArgumentExamples,
|
|
34978
|
+
commands: commandCatalog,
|
|
34979
|
+
readCommands,
|
|
34980
|
+
writeCommands,
|
|
34981
|
+
sessionBehavior: [
|
|
34982
|
+
"Read meta.session.source and meta.session.namespaces to understand whether data came from local cache, remote refresh, dry-run, or server-only execution.",
|
|
34983
|
+
"Use --refresh before a local-capable command when the cached snapshot may be stale.",
|
|
34984
|
+
"A mutation is durable only when meta.session.committed is true."
|
|
34985
|
+
],
|
|
34986
|
+
writes: [
|
|
34987
|
+
"Use MCP tools for fine-grained project edits.",
|
|
34988
|
+
"Use top-level CLI only for link/sync/build/publish/domains/permissions/discovery workflows."
|
|
34989
|
+
],
|
|
34990
|
+
visionVerificationLoop: [...mcpVisionVerificationLoop],
|
|
34991
|
+
screenshotVerification: screenshotVerificationSummary
|
|
34992
|
+
},
|
|
34993
|
+
llmDocSections
|
|
34994
|
+
)
|
|
34550
34995
|
},
|
|
34551
34996
|
mcp: {
|
|
34552
34997
|
manual: mcpManual,
|
|
34553
|
-
json:
|
|
34554
|
-
|
|
34555
|
-
|
|
34556
|
-
|
|
34557
|
-
"
|
|
34558
|
-
|
|
34559
|
-
|
|
34560
|
-
|
|
34561
|
-
|
|
34562
|
-
|
|
34563
|
-
|
|
34564
|
-
|
|
34565
|
-
|
|
34566
|
-
|
|
34567
|
-
|
|
34568
|
-
|
|
34569
|
-
|
|
34570
|
-
|
|
34571
|
-
|
|
34572
|
-
|
|
34573
|
-
|
|
34574
|
-
|
|
34575
|
-
|
|
34576
|
-
|
|
34577
|
-
|
|
34578
|
-
|
|
34579
|
-
|
|
34580
|
-
|
|
34581
|
-
],
|
|
34582
|
-
visionVerificationLoop: [...mcpVisionVerificationLoop],
|
|
34583
|
-
mcpArgumentExamples,
|
|
34584
|
-
screenshotVerification: screenshotVerificationSummary
|
|
34585
|
-
}
|
|
34998
|
+
json: mergeDocSections(
|
|
34999
|
+
"mcp",
|
|
35000
|
+
{
|
|
35001
|
+
topic: "mcp",
|
|
35002
|
+
title: readCliDocTitle("manual-mcp"),
|
|
35003
|
+
startup: [
|
|
35004
|
+
"webstudio init --link <api-share-link> --json",
|
|
35005
|
+
"webstudio permissions --json",
|
|
35006
|
+
"webstudio mcp"
|
|
35007
|
+
],
|
|
35008
|
+
discovery: [
|
|
35009
|
+
"tools/list",
|
|
35010
|
+
"resources/list",
|
|
35011
|
+
"meta.index",
|
|
35012
|
+
"meta.guide",
|
|
35013
|
+
"meta.get_more_tools"
|
|
35014
|
+
],
|
|
35015
|
+
resources: [
|
|
35016
|
+
"webstudio://project/status",
|
|
35017
|
+
"webstudio://project/tools",
|
|
35018
|
+
"webstudio://project/guide"
|
|
35019
|
+
],
|
|
35020
|
+
visionVerificationLoop: [...mcpVisionVerificationLoop],
|
|
35021
|
+
mcpArgumentExamples,
|
|
35022
|
+
screenshotVerification: screenshotVerificationSummary
|
|
35023
|
+
},
|
|
35024
|
+
mcpDocSections
|
|
35025
|
+
)
|
|
34586
35026
|
}
|
|
34587
35027
|
};
|
|
34588
35028
|
const man = (options) => {
|
|
@@ -39411,14 +39851,7 @@ const mcpOptions = (yargs) => yargs.example(
|
|
|
39411
39851
|
).example(
|
|
39412
39852
|
"MCP tool: meta.guide",
|
|
39413
39853
|
"Ask for the recommended workflow and relevant tools"
|
|
39414
|
-
).epilogue(
|
|
39415
|
-
[
|
|
39416
|
-
"Plain `webstudio mcp` starts the stdio MCP server.",
|
|
39417
|
-
"Startup marks cached ProjectSession data stale so MCP tools read the current Builder dev build.",
|
|
39418
|
-
"After startup, MCP clients discover capabilities with tools/list, resources/list, meta.index, meta.guide, and meta.get_more_tools.",
|
|
39419
|
-
"stdout is reserved for MCP JSON-RPC messages while the server is running."
|
|
39420
|
-
].join("\n")
|
|
39421
|
-
);
|
|
39854
|
+
).epilogue(readCliDoc("mcp-startup-epilogue"));
|
|
39422
39855
|
const mcp = async () => {
|
|
39423
39856
|
const connection = await resolveApiConnection();
|
|
39424
39857
|
const apiConnection = {
|