Files
webstudio/packages/cli/src/error-codes.ts
Oleg Isonen dde30ffb54 feat: Improve MCP authoring, compact output, and agent onboarding (#5883)
## Summary

This improves how agents discover, author, inspect, and verify Webstudio
projects while reducing unnecessary MCP context usage.

## What changed

- Adds an **Agents** section to Project Settings with ready-to-run setup
commands and client configuration for Claude Code, Codex, Cursor, and VS
Code.
- Makes large list and schema responses compact and paginated by
default, with **verbose** available when complete records or diagnostics
are needed.
- Applies consistent compact output to assets, instances, styles, design
tokens, CLI schemas, and project-session metadata.
- Returns actionable expression warnings for props, resources, and
Collection bindings, including unknown variables and risky render-time
mutation resources.
- Improves Collection expression guidance so agents can bind array items
with the correct scoped variables.
- Reports rendered audit outcomes explicitly as complete, partial,
confirmation-required, or failed.
- Expands runtime output schemas so MCP clients can validate responses
reliably.
- Strengthens the packaged CLI smoke workflow with a realistic
seven-page stdio MCP scenario.

## Architecture

- Consolidates `project-build` from 65 file-oriented entrypoints to 11
architecture-owned surfaces.
- Separates the core model, contracts, runtime authoring, transfer,
state, project sessions, MCP, visual tooling, persistence codecs, and
authenticated server services.
- Isolates Node-only JSX evaluation from browser-safe transfer utilities
and authenticated server modules.
- Keeps persistence codecs independent from authenticated database
services, preventing unrelated module initialization.
- Defines shared instance-path types once and reuses them across runtime
modules.
- Preserves Immer initialization through explicit package side-effect
metadata.
- Adds package tests that prevent a return to source-file entrypoints or
generic exposure of Node-only surfaces.

## Validation

- Full repository checks, tests, typechecks, generated-file checks, and
fixtures
- All 163 Builder test files and 2,141 tests
- All 71 project-build test files and 1,794 tests
- Lint and package-boundary validation
- Full packed CLI release smoke test, including install, preview, agent
setup, seven-page stdio MCP workflow, rendered audit, and structured
commands
2026-07-15 18:11:28 +02:00

65 lines
2.1 KiB
TypeScript

import {
getApiCompatibilityMessage,
getApiErrorCode,
} from "@webstudio-is/http-client";
import {
formatValidationIssues,
getValidationIssues,
} from "@webstudio-is/project-build/runtime";
const missingProjectOwnerForTokenPattern =
/^Project owner can't be found for token\b/;
const getErrorMessage = (error: unknown) =>
typeof error === "object" &&
error !== null &&
"message" in error &&
typeof error.message === "string"
? error.message
: error instanceof Error
? error.message
: String(error);
export const getStableErrorCode = (error: unknown) => {
const apiErrorCode = getApiErrorCode(error);
if (apiErrorCode !== undefined) {
return apiErrorCode;
}
if (typeof error === "object" && error !== null && "code" in error) {
const code = (error as { code?: unknown }).code;
if (typeof code === "string") {
return code;
}
}
};
export const isMissingApiAccessError = (error: unknown) => {
const message = getErrorMessage(error);
return missingProjectOwnerForTokenPattern.test(message);
};
export const getCliErrorSummary = (error: unknown, command = "mcp") => {
const compatibilityMessage = getApiCompatibilityMessage(error, {
updateCommand: "npm install -g webstudio@latest",
runLatestCommand: `npx webstudio@latest ${command}`,
});
if (compatibilityMessage !== undefined) {
return compatibilityMessage;
}
const message = getErrorMessage(error);
if (missingProjectOwnerForTokenPattern.test(message)) {
return "This project cannot be accessed through the Builder API with the current share link/token. Enable API access in the share-link settings, then relink the project with `webstudio init --link <share-link> --json`.";
}
return message;
};
export const getCliErrorMessage = (error: unknown, command = "mcp") => {
const message = getCliErrorSummary(error, command);
const issues = getValidationIssues(error);
return issues === undefined || issues.length === 0
? message
: `${message}\n${formatValidationIssues(issues)}`;
};
export const getCliErrorIssues = getValidationIssues;