Commit Graph
4090 Commits
Author SHA1 Message Date
Oleg Isonen b451dc8f3b fix: refresh content database diagnostics after save 2026-08-02 10:24:38 +01:00
Oleg Isonen 8c0e1b5042 fix: measure only bundled content database bytes 2026-08-02 10:17:34 +01:00
Oleg Isonen 17d0544283 fix: avoid duplicate publish warning toasts 2026-08-01 22:07:32 +01:00
Oleg Isonen 4ae5a450a3 fix: constrain Query tab portal 2026-08-01 09:32:46 +01:00
Oleg Isonen 96e016412b feat: expose counted content databases 2026-08-01 09:30:07 +01:00
Oleg Isonen ba26c8dc94 fix: contain Assets query scroller 2026-08-01 09:18:24 +01:00
Oleg Isonen a77f9e953a fix: clarify content database sizes 2026-08-01 09:15:51 +01:00
Oleg Isonen 04dd332888 fix: constrain Assets query editor 2026-08-01 09:14:17 +01:00
Oleg Isonen b2f0621de2 feat: clarify Assets query diagnostics 2026-08-01 09:08:00 +01:00
Oleg Isonen a5a41c6d8f fix: make Assets query source scrollable 2026-08-01 08:55:58 +01:00
Oleg Isonen 3ccb46cec7 fix: restore Marketplace settings and optimize Assets publishing (#5964)
## Outcome

Restore the Marketplace section for projects without existing
marketplace metadata, make the complete review-submission workflow
available over MCP, clarify shared Assets database diagnostics, and
reduce published database size by materializing fully static Assets
queries.

## Implementation

### Marketplace and MCP

- Initialize the Marketplace form from a safe partial default instead of
rendering nothing when metadata is unconfigured.
- Keep review submission disabled until the complete metadata schema is
valid.
- Allow `get-marketplace-product` to return `null` and
`update-marketplace-product` to create the first marketplace product
through ProjectSession/MCP.
- Add a confirmed `submit-marketplace-product` server operation that
validates configured metadata before setting review status to `PENDING`.
- Document the MCP workflow: upload the thumbnail, update metadata,
publish production, then submit.
- Correct the Marketplace thumbnail upload example to use the current
MCP input field.

### Assets database

- Show query size and merged published-database size separately in
resource diagnostics.
- Clarify that only the merged database counts toward the publish limit.
- Allow the Assets query editor to scroll long query source.
- Materialize fully static metadata-only Assets queries at publish time.
- Store materialized results as compact field columns and rows keyed by
a deterministic normalized-query hash.
- Serve materialized rows through the existing Assets response contract
without candidate documents or a runtime field catalog.
- Keep route- or variable-dependent queries on the existing
document-backed runtime path.
- Exclude overview-only fields from dynamic detail documents so the
merged database does not duplicate them.
- Preserve byte-limit selection, truncation diagnostics, integrity
verification, caching, and backward compatibility with existing
artifacts.

### Release

- Keep the release lockfile stable when preparing the CLI package.
- Regenerate runtime contracts, server-only API metadata, and CLI
documentation where required.

## Todo

- [x] Restore the empty Marketplace settings state
- [x] Prevent empty review submissions
- [x] Support first-time Marketplace metadata creation over MCP
- [x] Add MCP review submission
- [x] Document the end-to-end MCP workflow
- [x] Correct query and merged-database diagnostics
- [x] Make long Assets query source scrollable
- [x] Materialize static overview queries
- [x] Preserve dynamic detail-query behavior
- [x] Add regression coverage with fail/pass proof
- [x] Run relevant package and integration checks

## Verification

- [x] Content engine tests: 158 passed
- [x] Asset uploader tests: 179 passed
- [x] SDK tests: 505 passed
- [x] CLI tests: 921 passed
- [x] CLI prebuild integration tests: 46 passed
- [x] Builder Assets resource and diagnostics tests: 14 passed
- [x] Project runtime and ProjectSession tests: 133 passed
- [x] Builder API router tests: 30 passed
- [x] Protocol operation tests: 18 passed
- [x] Content engine build and declaration generation
- [x] Content engine, asset uploader, SDK, Builder, and CLI typechecks
- [x] Repository lint and formatting checks
- [x] Generated API and documentation checks
- [x] New materialization tests demonstrated failing with the
implementation disabled and passing after restoration

## Notes

- The representative five-post overview fixture shrinks from 2,122 bytes
to 1,197 bytes while returning the same sorted and paginated result.
- Materialization is intentionally limited to static, metadata-only
field queries without runtime asset fields. Unsupported or
data-incompatible queries safely use the existing runtime database.
- The complete `pnpm evaluations` agent suite was not run because
repository policy requires separate explicit approval.
- No database schema or migration changes are required.
2026-07-31 13:16:21 +02:00
Oleg Isonen efbc3098c4 feat: add queryable Assets resources (#5946)
Closes #5919
Ref #5920

## Outcome

Extend the existing Assets system resource with optional queries for
Markdown, JSON, and standard file metadata. Unconfigured Assets
resources retain the existing fetch-all behavior and activate none of
the content-query infrastructure.

Files are the authoring model. A standalone content engine converts an
immutable snapshot of only the files required by configured queries into
one bounded, deterministic runtime database. Builder preview, SSR, and
SSG use the same query semantics without requiring a database service
for a published site.

## Final architecture

```text
Markdown / JSON files
        │
        ▼
ContentSource adapter
(FS or Webstudio Assets)
        │ immutable snapshot
        ▼
ContentCompilationPlan
(union of configured query requirements)
        │
        ▼
ContentCompiler
(parse, normalize, discover fields, enforce budget)
        │
        ▼
ContentArtifact
(bounded, deterministic, immutable JSON)
        │
        ▼
ContentDatabase
(filter, OR groups, sort, paginate, project, read content)
        │
        ├── Builder preview
        ├── SSR runtime
        └── SSG build only
```

The authoring/storage layer owns mutable files. The content engine
consumes immutable snapshots and produces immutable, disposable
artifacts.


Query authoring is a separate OpenAPI-driven path:

```text
Assets REST OpenAPI operation
+ standard request JSON Schema
+ dynamic field paths
        │
        ▼
Generic OpenAPI adapter
        │ resolved schemas, controls, paths, and transport mapping
        ▼
Generic query-builder core and React renderer
        │ arbitrary provider-defined value
        ▼
Assets REST request adapter
        │
        ▼
{ query: value }
```

The selected standard OpenAPI operation is the only source of query UI
semantics. Request parameters and JSON Schema describe the editable
data; the generic renderer derives controls and owns layout.

### Activation and compilation

- The compiler does not index every asset. It combines all reachable
configured Assets-resource queries into one `ContentCompilationPlan`.
- Static constraints such as folder, path, and file type select
candidate files. Dynamic values such as a route-bound slug cannot reduce
the build-time candidate set.
- The plan contains the union of fields used by filtering, sorting,
routing, projection, excerpts, and requested full content.
- Documents shared by multiple resources are stored once in one
deployment-wide runtime database.
- Markdown/frontmatter, JSON properties, excerpts, and full bodies are
prepared only when required.
- No configured content query means no parsing, artifact, or shipped
runtime dependency. Fresh generated apps need no content-runtime
cleanup; incremental generation removes stale integration if a
previously configured query is deleted.

### Runtime database limit

- `CONTENT_DATABASE_MAX_BYTES` limits the complete serialized runtime
database, not source files, images, or unrelated assets.
- The default is `500 * 1024` bytes and is presented as 500 KiB.
- Counted data includes indexed metadata, frontmatter/JSON properties,
excerpts, the field catalog, serialization overhead, and full Markdown
bodies only when requested.
- Prepublish validation builds and serializes the exact database that
will be attached to the immutable build, so it knows the unbounded size,
bounded size, included documents, omitted documents, and affected
resources.
- Overflow never stores partial documents. Candidates are ordered by
`createdAt` descending, canonical path ascending, and stable document ID
ascending. Missing dates follow dated documents. A document that does
not fit is skipped while smaller later documents are still considered.
- Exceeding the limit warns but does not block publishing.
- Builder preview can report exact bounded versus unbounded results when
dynamic expressions have concrete preview values. Prepublish warnings
remain conservative for future route values.

### Snapshot consistency

The source contract guarantees a consistent compilation, while adapters
provide the mechanism:

- Webstudio Assets captures asset metadata and immutable content
references.
- Filesystem sources capture file identity and verify files did not
change before accepting the artifact.
- A changed source retries once, then fails clearly instead of producing
a mixed-revision database.
- This requires no universal snapshot service, source-tree copy, or new
versioned-asset infrastructure.

### Package ownership

- `@webstudio-is/content-engine`: runtime artifact schema, query
execution, field catalog, compact runtime statistics.
- `@webstudio-is/content-engine/compiler`: source snapshots, compilation
plans, Markdown/JSON parsing, deterministic compilation, byte
accounting, and compiler diagnostics. This entry exists to keep
Remark/YAML/future MDX dependencies out of runtime bundles.
- `@webstudio-is/query-builder`: resolves standard OpenAPI operation
schemas into an internal provider-neutral editor model, validation,
mutations, and source serialization. It owns no Assets,
provider-authored UI contract, or fixed REST-query semantics.
- `@webstudio-is/query-builder/react`: container-neutral schema renderer
whose layout is renderer policy. It remains separate from the content
engine.
- SDK: Webstudio Assets/Resource domain models and mapping Webstudio
expressions into generic content requirements.
- Protocol: external Assets REST/OpenAPI transport contracts.
- Asset uploader/repository: asset and folder mutations, generic
metadata, immutable byte references, and storage access. Its hosted
adapter supplies Webstudio Assets snapshots and parsed-metadata cache
persistence to the content engine; parsing, artifact creation, and query
semantics remain engine-owned.
- Builder and generated-app integrations decide when to compile, cache,
embed, load, or discard a database.

### Runtime lifecycle

- Builder caches immutable `ContentDatabase` instances by source
revision plus compilation-plan hash and coalesces concurrent
compilation. Matching operations reuse the same instance; field
discovery uses a dedicated minimal all-properties plan that excludes
excerpts and bodies.
- SSR attaches the validated bounded database to the build and includes
the small runtime only when required.
- SSG uses the database only while generating pages and omits it and the
runtime from final output unless a future runtime-query feature requires
them.
- Local development compiles from the filesystem and uses identical
query semantics.
- Published pages query their local artifact; they do not call Builder
REST endpoints.
- Published artifacts need no external index store, invalidation,
garbage collection, SaaS content proxy, new bucket, or new environment
variable.

## Implemented foundation

These existing parts remain useful and should be moved behind the final
ownership boundaries rather than reimplemented.

- [x] Upgrade the existing Assets system resource in place and preserve
unconfigured fetch-all behavior.
- [x] Implement typed filtering, nested boolean groups, deterministic
sorting, pagination, projections, dynamic values, and content hydration.
- [x] Add Markdown frontmatter, excerpt, JSON-property, and
field-catalog extraction.
- [x] Add reusable query-control implementations and a separately
imported React UI as a foundation for the final OpenAPI-driven contract.
- [x] Add Assets query authoring and dynamic field discovery as existing
behavior to migrate into the Assets OpenAPI operation.
- [x] Add synchronized visual and editable expression authoring.
- [x] Unify Assets REST operations under `/rest/assets/*`.
- [x] Define authenticated collection, item, content, upload, folder,
query, field-catalog, and OpenAPI operations.
- [x] Support Builder cookie authentication and public API token
authentication.
- [x] Add Builder preview, MCP/CLI operations, SSR execution, SSG path
generation, and conditional activation.
- [x] Add revision-keyed parsed metadata persistence for the hosted
Builder.
- [x] Add focused query, API, authorization, Builder, CLI, SSR, SSG,
migration, and fixture coverage.

## Remaining implementation plan

### 1. Establish the content engine

- [x] Rename the generic `@webstudio-is/asset-resource` implementation
to `@webstudio-is/content-engine`.
- [x] Move existing behavior instead of creating a parallel
implementation.
- [x] Keep the primary entry runtime-only and add only the compiler
entry needed for bundle separation.
- [x] Remove the old package after all consumers migrate.
- [x] Ensure the engine has no Builder, SDK, asset-uploader, PostgreSQL,
R2, or deployment-target dependency.

### 2. Define source snapshots and compilation plans

- [x] Introduce `ContentSource.openSnapshot()` and a revision-bearing
`ContentSourceSnapshot`.
- [x] Include canonical path, stable document ID, content type,
immutable content reference, size, and optional `createdAt`.
- [x] Implement Webstudio Assets and filesystem snapshot guarantees
using their adapter-specific mechanisms.
- [x] Introduce `ContentCompilationPlan` for the union of reachable
configured resource requirements.
- [x] Separate statically selectable candidates from dynamic runtime
predicates.
- [x] Add mutation-during-compilation tests for replacement, deletion,
folder movement, and filesystem changes.

### 3. Separate storage from content processing

- [x] Keep upload, replacement, folders, byte storage, revisions, and
generic metadata in the Assets repository/uploader.
- [x] Move parsing, excerpts, field discovery, query execution, and
artifact creation into the content engine.
- [x] Remove content-index coordination from asset mutation business
logic.
- [x] Preserve original source `createdAt` across content replacement
and expose it as optional queryable metadata.
- [x] Keep hosted parsed-document persistence behind the content
compiler's optional cache interface.

### 4. Build deterministic compilation

- [x] Move the existing Markdown, frontmatter, JSON, canonicalization,
hashing, document-building, and tests into the compiler.
- [x] Keep frontmatter behind a dedicated module and continue using the
existing Remark/Micromark pipeline.
- [x] Parse only candidate files and only the tiers required by the
compilation plan.
- [x] Deduplicate documents and fields required by multiple resources.
- [x] Define a versioned, deterministic `ContentArtifact` with integrity
information.
- [x] Keep verbose parse and omission diagnostics outside the runtime
artifact.
- [x] Reject incompatible artifact versions cleanly.

### 5. Enforce the deployment-wide database budget

- [x] Replace the old asset-index limit with
`CONTENT_DATABASE_MAX_BYTES`, defaulting to 500 KiB.
- [x] Have applications read configuration and pass the byte limit into
the compiler.
- [x] Measure the exact serialized database, including selected bodies
and overhead.
- [x] Implement deterministic skip-and-continue packing of complete
documents.
- [x] Return compiler diagnostics with unbounded/bounded bytes,
included/omitted counts, omitted identities, largest contributors, and
affected resources.
- [x] Expose only compact artifact statistics at runtime through
`ContentDatabase.getStats()`.
- [x] Add exact boundary, deterministic ordering, deduplication, and
oversized-document tests.

### 6. Finalize the runtime database

- [x] Define `ContentDatabase` over an immutable artifact.
- [x] Preserve filtering, nested AND/OR groups, sorting, offset/limit,
projection, field references, and content retrieval.
- [x] Expose `getFieldCatalog()` and compact `getStats()`.
- [x] Keep Markdown/YAML/compiler dependencies out of the runtime entry.
- [x] Add execution guards and maximum-size runtime benchmarks.

### 7. Make query authoring OpenAPI-driven

The selected standard OpenAPI operation is the complete query-authoring
contract. The query builder resolves parameters and request-body JSON
Schema, derives its internal editor model, and applies renderer-owned
layout policy. It must not embed or fetch a second capabilities/UI
language through `x-webstudio-query` or another side channel.

- [x] Remove `x-webstudio-query` and all vendor query-definition
metadata from the Assets OpenAPI operation.
- [x] Resolve local OpenAPI references and derive the editable request
value, defaults, validation, labels, choices, arrays, objects, and
unions solely from standard operation parameters and request-body JSON
Schema.
- [x] Represent dynamic Assets field paths with standard JSON Schema
vocabulary in the `queryAssets` request schema.
- [x] Keep the normalized editor representation internal to
query-builder; do not expose another provider-authored capabilities
contract.
- [x] Remove provider-controlled layout metadata such as `group`; make
compact scalar packing and all other layout renderer policy.
- [x] Keep Webstudio expression binding as a consumer/editor concern
layered over schema values, not part of the OpenAPI contract.
- [x] Preserve the existing Assets filter, sort, output selection,
full-content/range selection, limit/offset, editable source, and
configured-field behavior.
- [x] Keep the Assets resource adapter responsible for serializing the
edited query into its request body.
- [x] Remove the obsolete Assets query-capabilities endpoint, URL, and
UI-side capability parsing.
- [x] Add a non-Assets OpenAPI proof with differently named parameters
and no vendor metadata.
- [x] Verify the generic packages contain no Assets imports, fixed
Assets property contract, or provider-authored layout model.
- [x] Update focused core, React, SDK, protocol/OpenAPI, Builder, and
source round-trip tests.

### 8. Manage ContentDatabase lifecycle in Builder

- [x] Cache databases by source revision plus normalized
compilation-plan hash.
- [x] Coalesce concurrent compilation requests.
- [x] Reuse cached database instances across field discovery,
autocomplete, query preview, and response preview when their normalized
compilation plans match.
- [x] Replace it when source revision or query requirements change.
- [x] Preserve the optional revision-keyed hosted parsed-document cache
without making it a source of truth.
- [x] Show exact preview warnings when concrete values reveal missing
bounded results.

### 9. Materialize and verify immutable builds

- [x] Compile and serialize the exact deployment-wide database during
prepublish validation.
- [x] Attach that validated bounded database to the immutable build
without rebuilding it from later asset state.
- [x] Show non-blocking prepublish warnings with database bytes,
omissions, and potentially affected resources.
- [x] Avoid claiming exact future route matches when dynamic values are
unknown.
- [x] Include the database/runtime only when a reachable configured
query requires them.
- [x] Ensure detail resources requesting Markdown content include all
statically eligible bodies needed by dynamic routes.

### 10. Integrate all targets

- [x] SSR: load the build's bounded database and conditionally include
the small runtime.
- [x] SSG: query the same database during generation, then omit
database/runtime output when no runtime query is needed.
- [x] Local/CLI: compile from the filesystem source with the same
semantics.
- [x] Preserve overview pagination, alternative route fields,
draft-as-user-data behavior, and full article rendering.
- [x] Verify ordinary Assets and fresh query-free sites perform no
parser, artifact, content-runtime dependency install, or cleanup work.

### 11. Correct API and package ownership

- [x] Move external Assets REST/OpenAPI contracts to
`@webstudio-is/protocol`.
- [x] Keep Webstudio domain models and Assets system-resource
configuration in the SDK.
- [x] Keep both cookie and token authentication behavior on the unified
Assets REST surface.
- [x] Remove pass-through route wrappers/reexports that add no transport
behavior.
- [x] Keep published runtime queries local to the artifact rather than
routing them through Builder REST.

### 12. Remove superseded deployment infrastructure

- [x] Remove external deployment-index upload, fetch, invalidation,
cleanup, and garbage-collection code.
- [x] Remove the SaaS asset-origin adapter requirement; close
webstudio-is/webstudio-saas#652 as superseded because it has no
independent purpose.
- [x] Remove index-bucket compatibility configuration and avoid adding
Infisical variables.
- [x] Remove obsolete external-index paths, package dependencies,
routes, scripts, and tests.
- [x] Consolidate unreleased intermediate migrations where safe and
retain only schema required by the final hosted cache/API design.

### 13. Verification and release readiness

- [x] Move and preserve existing tests while changing ownership; add new
tests only for changed contracts and behavior.
- [x] Run content-engine compiler/runtime tests, query-builder tests,
SDK/protocol/API tests, Builder tests, CLI tests, and affected
typechecks.
- [x] Run formatting, generated-file idempotence, fixtures, clean
Supabase-compatible migrations, E2E shards, and complete agent
evaluations.
- [x] Verify SSR and SSG conditional inclusion and query-free generated
package manifests.
- [x] Run the five-article MCP blog workflow: authoring, field
discovery, overview, dynamic detail routes, full Markdown rendering,
publishing, and published-site verification.
- [x] Run a maximum-budget database test and a
mutation-during-compilation test.
- [x] Perform a final architecture, security, API compatibility,
migration, bundle, correctness, and DRY review.
- [x] Reconcile every checkbox and replace the verification section with
results from the final architecture before release.

## Future MDX work

MDX is intentionally separate from this release.

- The compiler contract should allow a future build-only MDX parser.
- MDX compilation must not enter the published runtime.
- Embedded JSX must use an explicit compiled representation rather than
runtime source evaluation.
- Webstudio components, tokens, styles, and component allowlists remain
Webstudio integration concerns.
- The future MDX work should reuse `ContentArtifact` and
`ContentDatabase` where practical.

## Superseded design

The following earlier design choices are no longer the target
architecture:

- GROQ or GraphQL as the Assets query language.
- One external or long-lived index object per resource/query.
- A deployment index fetched by the Worker from SaaS/CDN infrastructure.
- Lazy production reads of source Markdown bodies.
- A separate index bucket, asset origin, invalidation service, or
garbage collector.
- A 4 MiB published index limit.
- Rebuilding an old build's database from the current mutable asset set.
- Bundling query infrastructure into projects without a configured
content query.

## Verification baseline

The embedded runtime-database architecture previously passed the checks
below. The OpenAPI-driven query-authoring change additionally passed:

- Query-builder core: 4 files / 19 tests.
- Query-builder React: 1 file / 7 tests.
- SDK Assets source/config: 1 file / 7 tests.
- Protocol Assets OpenAPI: 1 file / 9 tests, including independent
OpenAPI validation.
- Builder Assets OpenAPI description: 1 file / 5 tests.
- Query-builder, React, SDK, protocol, and Builder typechecks.
- Package-boundary validation and formatting of every affected file.

Local verification baseline:

- Content engine: 15 files / 104 tests.
- Asset uploader: 24 files / 175 tests.
- Builder: 204 files / 2,423 tests.
- CLI: 54 files / 866 tests.
- Complete workspace typecheck, formatting, lint, package boundaries,
generated fixtures, and fixture builds.
- The complete migration history applied successfully to a fresh
Supabase-compatible database, including every migration after the
consolidated Assets migration.
- Builder production build and full local E2E suite passed.
- Complete agent evaluations passed: authenticated page (170,859 ms),
design input (207,101 ms), and font assets (67,050 ms).
- Final review additionally verified correct REST edit/view/build
permits, cookie and public-token read paths, immutable snapshot retries,
exact database budgeting, query-free dependency omission, and SSR/SSG
conditional runtime inclusion.

Final staging verification passed against the embedded runtime-database
architecture: MCP uploaded and updated five Markdown articles,
discovered dynamic frontmatter fields, previewed a five-item sorted
overview and one full-body slug query, updated both Assets resources,
found zero binding issues, rendered `/blog` and `/blog/dynamic-routes`
at HTTP 200, published build version 266, and verified both published
routes at HTTP 200 with the expected article metadata and Markdown body.
The workflow also found and fixed offset-form asset timestamps failing
canonical datetime validation and made MCP `preview.start({ port: 0 })`
correctly select an available local port.

## Release constraints

- No new SaaS content service, bucket, or environment variable.
- No published-site database dependency.
- No parser/compiler dependency in query-free sites or runtime-only
bundles.
- The validated content database is immutable build output.
- Publishing warnings do not block deployment.
- The selected standard OpenAPI operation and its request JSON Schema
are the only source of query UI semantics.
2026-07-31 00:17:46 +02:00
Oleg Isonen c0687e3323 fix: Accept CSS strings in animation keyframes (#5956)
## Summary

Allow MCP `update-props` callers to configure `animationAction`
keyframes with normal CSS strings, including values such as `transform:
"translateX(-75%)"`.

Use one SDK-owned animation authoring schema in both the Builder UI and
MCP so CSS parsing, timing defaults, and validation cannot drift between
entry points.

## Root cause

The Builder UI and MCP did not share an authoring contract. Builder
controls produced Webstudio's structured style values and animation
factories supplied timing objects, while MCP passed its input directly
toward the persisted prop schema. As a result, normal CSS strings failed
deep Zod validation and omitted timing objects were rejected.

## Implementation

- Add a shared `createAnimationActionInput` schema factory to the SDK.
- Inject the CSS parser into the schema factory to avoid adding an `sdk`
→ `css-data` dependency cycle.
- Use the shared schema in both Builder animation validation and MCP
`update-props`.
- Accept raw CSS strings or existing structured Webstudio values in
`keyframes[].styles`.
- Parse string values before persistence and default omitted animation
`timing` to an empty options object.
- Update Animation Group guidance and regenerate the runtime operation
contract.
- Preserve strict validation for existing structured animation style
values.

## Checklist

- [x] Add regression coverage for the reported horizontal scroll
payload.
- [x] Verify the regression fails before implementation and passes after
it.
- [x] Add SDK coverage for shared animation authoring normalization.
- [x] Use the shared authoring schema in Builder and MCP.
- [x] Verify package boundaries and generated runtime contracts.
- [x] Run affected typechecks, targeted tests, lint, and formatting.
- [x] Run the complete agent evaluation suite.
- [ ] Resolve evaluation read-budget failures: `authenticated-page-v1`
and `design-input-v1` failed only `boundedReads`.

## Validation

Passed:

- `pnpm --filter @webstudio-is/sdk test --
src/schema/animation-schema.test.ts`
- `pnpm --filter @webstudio-is/project-build test --
src/runtime/props.test.ts src/mcp.test.ts`
- `pnpm --filter @webstudio-is/sdk typecheck`
- `pnpm --filter @webstudio-is/project-build typecheck`
- `pnpm --filter @webstudio-is/builder typecheck`
- `pnpm check:package-boundaries`
- `pnpm exec oxlint --deny-warnings <changed source and test files>`
- `pnpm exec oxfmt --check <changed source and test files>`
- `pnpm check:generated-api`
- `font-assets-v1` agent evaluation

Agent evaluation findings:

- `authenticated-page-v1`: failed only `boundedReads`; all functional,
audit, binding, privacy, and visual checks passed.
- `design-input-v1`: failed only `boundedReads`; all functional, audit,
responsive, design-system, privacy, and visual checks passed.
- `font-assets-v1`: passed all checks.
2026-07-29 17:37:56 +02:00
Oleg Isonen 0b192c7802 fix: Sort style sources with temporary local source (#5949)
## Summary

- Allow style sources to be reordered when the displayed local source
has not been persisted yet.
- Submit only attached style source IDs to the runtime reorder
operation.
- Add regression coverage for reordering tokens alongside a temporary
local source.

## Root cause

The style panel displays a temporary local style source until local
styles are persisted. Sorting included that temporary ID in the runtime
mutation, but the runtime accepts only attached style source IDs and
rejected the entire reorder.

## Todo

- [x] Filter temporary style source IDs from reorder mutations.
- [x] Add regression coverage.
- [x] Run targeted tests, lint, formatting, and Builder typecheck.

## Verification

- `pnpm --filter @webstudio-is/builder test --
app/builder/features/style-panel/style-source-section.test.ts` — 12
tests passed
- `pnpm exec oxlint --deny-warnings
apps/builder/app/builder/features/style-panel/style-source-section.tsx
apps/builder/app/builder/features/style-panel/style-source-section.test.ts`
- `pnpm exec oxfmt --check
apps/builder/app/builder/features/style-panel/style-source-section.tsx
apps/builder/app/builder/features/style-panel/style-source-section.test.ts`
- `pnpm --filter @webstudio-is/builder typecheck`
2026-07-24 15:45:48 +02:00
Oleg Isonen 7eb58664b0 fix: harden asset folder uploads and selection (#5939)
## Summary

Fixes folder uploads and asset-manager selection behavior.

## Changes

- Preserve folder IDs for newly uploaded assets.
- Place duplicate assets into the dropped folder, including server-side
deduplication and assets already uploading.
- Handle browser `NotFoundError` cases while reading dropped
directories.
- Keep lasso selection anchored correctly while scrolling.
- Add `Cmd/Ctrl+A` to select all currently rendered assets and folders.
- Document the new shortcut in the keyboard shortcuts dialog.
- TIFF support was removed in the base branch.

## Verification

- [x] Asset upload and directory-drop tests
- [x] Asset-manager tests
- [x] Keyboard shortcuts dialog tests
- [x] Builder typecheck
- [x] Formatting and diff checks
2026-07-21 16:35:04 +02:00
Oleg Isonen 085f705cc4 fix: remove unsupported TIFF assets (#5938)
## Summary

- Remove `.tif` and `.tiff` from supported asset extensions.
- Stop categorizing TIFF files as images in the asset manager.
- Update SDK URL coverage to reflect the supported direct-served image
formats.

## Why

The asset manager classified TIFF files as images, but the browser and
image optimization pipeline cannot reliably render TIFF thumbnails.
Treating TIFF as supported created broken previews.

## Verification

- SDK asset tests: 95 passed
- Formatting completed
- Diff checked against `main`
2026-07-21 15:44:14 +02:00
Oleg Isonen 54aa7be145 fix: Make MCP authoring reliable across assets, styles, and embeds (#5932)
Closes #5924
Closes #5925
Closes #5926
Closes #5927
Closes #5928
Closes #5929

## Outcome

Makes MCP and CLI authoring predictable across project-wide CSS
variables, font uploads, retried asset uploads, destructive asset
selection, design-token collisions, and SVG HtmlEmbed edits.

## Delivered

### Project-global CSS variables

- [x] `define-css-variable` writes to `ROOT_INSTANCE_ID` / `:root`
instead of the home-page Body.
- [x] Breakpoint and overwrite behavior is preserved, and compact
results identify the root scope.
- [x] Existing body-local declarations remain untouched.
- [x] Runtime and Builder integration tests cover root selection and
generated project behavior.

### Font metadata and upload overrides

- [x] Static fonts prefer authoritative `OS/2.usWeightClass`.
- [x] Fallback matching normalizes spaces, hyphens, and underscores and
checks specific aliases before shorter ones.
- [x] Explicit format and partial metadata overrides travel through
HTTP, filesystem, and S3 upload paths and are validated after merging
with detected metadata.
- [x] Regression tests cover ExtraBold, Extra-Bold, Semi Bold Italic,
Ultra Light, valid weight classes, invalid weight classes, partial
overrides, and invalid overrides.

### Idempotent asset uploads

- [x] API uploads compute a project-scoped SHA-256 content hash.
- [x] Sequential and concurrent duplicate uploads reuse the existing
asset and return `deduplicated: true`.
- [x] `force: true` bypasses deduplication for intentional duplicates.
- [x] A partial unique index enforces one non-null content hash per
uploader project.
- [x] Stale reservations are cleaned up and active concurrent uploads
are bounded by polling and an actionable retry error.
- [x] HTTP, protocol, uploader, and CLI tests cover hash reuse,
uniqueness races, force propagation, and result markers.

The migration does not backfill historical files. Existing assets begin
participating in deduplication when uploaded through the new path;
matching content keeps the existing asset's metadata rather than
silently rewriting it.

### Consistent asset inputs and permissions output

- [x] `delete-asset` exposes exact `assetIds` and explicit
`assetIdPrefixes`.
- [x] The legacy `assetIdsOrPrefixes` input remains accepted and is
marked deprecated.
- [x] Exact ids no longer accidentally select longer prefixed ids.
- [x] `webstudio permissions` prints a readable role/capability summary
by default while `--json` remains unchanged for machine callers.
- [x] Help and discovery describe JSON output as optional.
- [x] Runtime, CLI, metadata, and generated-contract tests cover
canonical and compatibility behavior.

### Deterministic fragment design tokens

- [x] Fragment insertion reconciles incoming tokens against project
tokens and earlier tokens in the same fragment.
- [x] Equal name/style tokens are reused instead of creating suffixed
twins.
- [x] Same-name/different-style fragments require an explicit `ours`,
`theirs`, or `merge` policy at the public runtime boundary.
- [x] Builder's established internal paste behavior retains its explicit
incoming-value default.
- [x] `create-design-token` accepts documented CSS strings through the
property-aware CSS parser as well as typed style values.
- [x] Tests cover same-fragment reuse/conflicts, persisted tokens,
explicit policies, and CSS string parsing.

### Editable SVG HtmlEmbed content

- [x] HtmlEmbed validation uses parse5 parser errors and source
structure instead of serialization-string equality.
- [x] Valid inline SVG is accepted without silently normalizing authored
markup.
- [x] Fragment insertion now uses the same validator as prop update and
text replacement paths.
- [x] Malformed markup is rejected before mutation.
- [x] Regression tests cover realistic SVG, parser failures, and
no-partial-mutation behavior.

## Verification

- [x] `pnpm checks`: all workspace tests, typechecks, lint, package
boundaries, generated API/docs checks, and fixtures passed on the final
committed tree.
- [x] `pnpm --filter webstudio test:release-smoke`: packaged install,
compact comparison, preview, agent workflow, stdio MCP, and structured
commands passed.
- [x] Prisma schema validation passed with test connection variables.
- [x] Two minimally prompted weak-model subagents independently
exercised the changed CLI/MCP discovery and focused workflows.
- [x] The subagent-found stale `permissions --help` requirement was
fixed, regression-tested, and retested.
- [x] Final diff and worktree are clean.
2026-07-21 14:36:54 +02:00
Oleg Isonen 918e569fd4 fix: Show publish warnings immediately (#5935)
## Summary

Show client-side pre-publish audit findings as soon as the user starts
publishing, and apply the Builder's standard text styling to warning
banners.

## Root cause

The cloud publish audit ran inside an async form action, while the
static export audit ran inside an async transition. React deferred their
ordinary state updates until those async operations completed, so
warnings could appear only after publishing or export finished even
though validation itself ran synchronously on the client.

## Changes

- Run the cloud publish audit in the synchronous button click handler
before starting the async publish transition.
- Run the static export audit before starting its async transition.
- Keep warnings non-blocking while preserving blocking audit errors.
- Render warning-banner content with the design-system `Text` component.

## Checklist

- [x] Show cloud publish warnings before publishing starts
- [x] Show static export warnings before export starts
- [x] Style warning text consistently
- [x] Run Builder tests
- [x] Run Builder typecheck
- [x] Run lint and formatting checks

## Verification

- `pnpm --filter @webstudio-is/builder test` — 2,351 tests passed
- `pnpm --filter @webstudio-is/builder typecheck`
- `pnpm exec oxlint --deny-warnings
apps/builder/app/builder/features/publish/publish.tsx`
- `pnpm exec oxfmt
apps/builder/app/builder/features/publish/publish.tsx`
2026-07-21 11:57:00 +02:00
Oleg Isonen 4ea8928880 fix: preserve legacy content through validation (#5933)
## Summary

- Keep the shared content-model validator strict during normal Builder
authoring.
- Report HTML and component nesting violations as publish warnings
instead of blocking legacy projects.
- Allow paste operations to retain violations already contained inside
legacy fragments and surface them as warnings.
- Continue rejecting new violations introduced at the paste destination
boundary.
- Remove obsolete empty content models from CodeText and Video so their
runtime-supported, HTML-valid children pass validation.

## Root cause

The new pre-publish audit applied current authoring constraints to
historical project trees. Some legacy structures, including old
Accordion triggers containing an h3 inside a button, were created by
earlier Webstudio templates and cannot satisfy the current HTML model
without migration. Blocking publish or paste would make untouched legacy
content unusable.

CodeText and Video also had metadata that rejected children their
renderers intentionally support. Those verified metadata mismatches are
corrected independently of the compatibility policy.

## Behavior

- New invalid nesting remains prevented by normal authoring operations.
- Existing invalid nesting produces a Publish warning and does not abort
publishing.
- Webstudio instance, HTML, JSX, and Webflow paste retain
fragment-internal violations and show a paste warning.
- Paste still validates the destination and cannot introduce a new
invalid parent-child relationship.
- Resource integrity and missing audit inputs still prevent publishing.

## Verification

- [x] Legacy button containing h3 reports a publish warning
- [x] Legacy invalid subtree pastes successfully with a warning
- [x] New paste destination violations remain rejected or use the
closest valid target
- [x] Valid legacy CodeText children pass validation
- [x] Valid Video source and track children pass validation
- [x] Project-build matcher and insert-target tests
- [x] Builder instance, HTML, JSX, and Webflow paste tests
- [x] Project-build and Builder typechecks
- [x] Focused oxlint and formatting checks
2026-07-21 11:31:38 +02:00
Oleg Isonen 620f8b54ed feat: Create blank text assets (#5931)
## Summary

- add a **Create text file** action to the Assets toolbar and shared
context/dropdown menu
- validate filenames against the central editable-asset registry, create
the empty file in the current asset folder, and open it in the text
editor
- keep simultaneous empty uploads distinct by including the filename in
the upload fingerprint
- keep internal Nano ID storage suffixes out of visible asset names and
subsequent content revisions
- show the immutable file extension beside the editable basename in
Asset settings

Asset querying, content hydration, structured data, bindings, generated
runtime support, and MCP integration remain owned by #5921.

## Verification

- Builder asset/text tests: 34 passed
- SDK asset tests: 110 passed
- project-build asset tests: 71 passed
- asset-uploader revision tests: 5 passed
- SDK, project-build, asset-uploader, and Builder typechecks
- lint and package-boundary checks

Ref #5824
2026-07-20 20:57:01 +02:00
Oleg Isonen 5016426bfb fix: Preserve resource URL expression formatting (#5916)
## What changed

- preserve the user’s original whitespace and newlines in resource URL
binding expressions

## Change of plan

Automatic expression formatting is not needed. Prop binding expressions
already preserve user-entered formatting; only resource URL bindings
were losing their newlines. This PR aligns resource URL bindings with
the existing prop binding behavior and does not add a formatter or
change expression formatting rules.

## Root cause

The resource URL expression was stored in an input hidden with the HTML
`hidden` attribute. Because its input type still defaulted to `text`,
the browser value-sanitization algorithm removed newline characters
before the form was serialized.

The URL form field now uses `type="hidden"`, which preserves the
original expression during form submission.

## Validation

- `pnpm --filter @webstudio-is/builder typecheck`
- `pnpm lint`
- `git diff --check`

Closes #5858
2026-07-20 17:01:47 +02:00
Oleg Isonen cfba520e6d feat: Open text assets in code editor (#5918)
## What changed

- open every textual asset type from the upload registry in an editable
CodeMirror dialog
- select installed CodeMirror language support by MIME type and use
plain text editing as the fallback
- support `txt`, `csv`, `md`, `js`, `css`, `json`, `html`, `xml`, and
`svg` without adding asset-specific language branches to the shared
editor
- keep the canvas mounted and interactive behind the dialog
- persist edits on blur, `Cmd/Ctrl+S`, or `Cmd/Ctrl+Enter` through the
asset replacement pipeline
- preserve folder and description metadata and repoint supported asset
references
- clean up failed replacement uploads instead of leaving orphan assets

## Impact

Users can open, edit, and persist all text-based upload formats directly
in the builder without replacing or reloading the canvas. New `text/*`
upload types will automatically become editable as plain text; installed
syntax support is selected by MIME type.

## Validation

- `pnpm --filter @webstudio-is/builder test --
app/builder/features/text-file-editor/text-file-utils.test.ts
app/builder/shared/assets/replace-asset.test.ts
app/builder/shared/asset-manager/asset-manager.test.tsx`
- `pnpm --filter @webstudio-is/builder typecheck`
- `pnpm exec oxlint --deny-warnings <changed files>`
- `pnpm exec oxfmt --check <changed files>`
- `git diff --check`
- verified the running dev server applied the changes through Vite HMR

Ref #5824
2026-07-20 13:42:06 +02:00
Oleg Isonen 9ce325b94c feat: Deep-link Builder instances (#5923)
## Summary

- add optional `instanceId` support to the shared Builder link
parameters used by `builderPath` and `builderUrl`
- synchronize the selected instance into the Builder URL without adding
a browser-history entry for every selection
- restore the selected page and full instance selector when opening an
instance deep link
- render a **Show element** link for pre-publish audit findings that
identify an instance
- switch to the affected page, select and scroll to the instance, and
close the publish popover when the link is used

## Why

The pre-publish audit introduced in #5922 identifies the invalid page
and instance, but its error was text-only. Users still had to locate the
offending element manually. A shared instance deep-link parameter also
makes these links copyable and reusable outside the audit UI.

## Impact

Builder URLs can now include `instanceId` alongside `pageId`. Existing
page-opening links continue using the same central
`builderPath`/`builderUrl` abstraction. Missing or stale instance IDs
safely fall back to the requested page.

## Validation

- focused Builder tests passed (4 tests)
- `@webstudio-is/builder` typecheck passed
- focused Oxlint passed
- focused Oxfmt check passed
- `git diff --check` passed
2026-07-20 01:40:42 +02:00
Oleg Isonen be906afb5b fix: validate projects before publishing (#5922)
## Summary

- add a reusable pre-publish audit pipeline with normalized findings and
extensible checks
- validate HTML content-model nesting and existing resource integrity
before regular and static publishing
- identify the affected page and instance in invalid-markup errors
- move generated HTML formatting from automatic `postbuild` to the
explicit local `build:debug` command

## Root cause

A project contained an invalid stored component hierarchy, with an `h2`
nested inside a paragraph. The Builder did not run a holistic
content-model validation before publishing, so the invalid hierarchy
reached static generation. The static fixture then ran `oxfmt`
automatically during `postbuild`; its parse failure made the otherwise
completed static build fail.

## Impact

Users now see a specific Builder error before publishing, including the
affected page and invalid nesting. Static publish CI no longer formats
generated HTML automatically, while developers can still produce
formatted output locally with `pnpm build:debug`.

## Validation

- 65 focused project-build tests passed
- `@webstudio-is/project-build` typecheck passed
- `@webstudio-is/builder` typecheck passed
- focused Oxlint passed
- focused Oxfmt check passed
- `git diff --check` passed
2026-07-19 23:43:28 +02:00
Oleg Isonen 0070fa66a1 ci: deduplicate builder E2E setup (#5917)
## What changed

- reuse the shared CI setup action in both Builder E2E jobs
- use one build command for CI and local E2E runs
- centralize shard filename parsing and suite-name formatting
- remove redundant suite-level shard filtering
- parse each E2E filename's shard metadata once

## Why

The merged image-asset PR introduced multiple owners for Builder E2E
setup, build dependencies, and shard filename semantics. Consolidating
them prevents CI and local behavior from drifting as the shard layout
evolves.

## Validation

- `pnpm --filter=@webstudio-is/builder test -- e2e/test-modules.test.ts`
- `pnpm --filter=@webstudio-is/builder typecheck`
- `pnpm lint`
- `pnpm e2e:builder:build`
- shell syntax and YAML parsing
- shard discovery returned shards 1–6
2026-07-18 10:43:56 +02:00
Oleg Isonen ef94d85ccf feat: drag image assets onto canvas (#5912)
## Summary

- allow dragging a single image asset from the Assets panel onto the
canvas
- insert an Image component with its source bound to the dragged asset
in one undoable mutation
- preserve asset-folder drops and canceled drags
- build the Builder once in CI and reuse the compact build artifact
across all E2E shards

## E2E timing

Recent CI showed shard test runtimes of roughly 101–145 seconds, while
every shard also repeated a roughly two-minute Builder build. The four
shards are already reasonably balanced, so a fifth shard would not
address the primary bottleneck.

The shared artifact is about 30 MB uncompressed and roughly 5 MB
compressed because checked-out public assets are excluded. This should
return individual shard jobs to the 2–3 minute range.

## Validation

- 45 focused unit tests
- image asset to canvas E2E using the prebuilt-artifact path
- image asset to folder regression E2E
- Builder typecheck
- lint
- package-boundary validation
- workflow YAML validation
- shell syntax validation
2026-07-18 09:15:02 +02:00
Oleg Isonen 7d7c23d30a fix: Center empty asset folder drop state (#5911)
## Summary

- center the reusable “Drop files here” state against the full
empty-folder area
- keep the Back thumbnail independently positioned and interactive
- add regression coverage for empty folders with additional content
- add a fourth builder E2E shard and split the serial asset-folder
workflows using measured CI durations

## Root cause

The Back thumbnail participated in the same column flow as the drop
state, reducing the drop state’s available height and shifting its
center downward.

The asset-folder E2E module also accumulated ten serial workflows and
became shard 1’s 214-second bottleneck.

## User impact

Empty folders now align the drop message consistently with the root
empty state and full-panel drag overlay.

The E2E split reduces shard 1’s measured workload from about 230 seconds
to a projected 113 seconds, with shard 4 at about 100 seconds.

## Validation

- focused asset tests: 62 passed
- E2E shard discovery test
- shard 1 and shard 4 module loading
- builder typecheck
- workspace typechecks
- lint
- package boundaries
- generated API and docs checks
- fixtures
- full workspace tests; three CLI subprocess tests initially timed out
under concurrent load and passed when rerun in isolation
2026-07-18 02:45:21 +02:00
Oleg Isonen cca9f93e3d feat: Improve asset folder move workflows (#5908)
## Summary

- use the design-system native scroll area and auto-scroll long asset
lists during internal drag operations
- add a shared **Move** action to thumbnail and context menus for
individual and multiselected assets and folders
- add a folder-only move dialog that excludes invalid descendant
destinations
- consolidate bulk move, duplicate, delete, and clipboard behavior into
shared asset-manager operations with undo/redo coverage
- simplify dialog state, folder exclusion traversal, and long-list E2E
setup

## User impact

Users can drag assets or folders to destinations outside the currently
visible part of a long panel, and can move one or many selected items
through an explicit folder picker.

## Validation

- `pnpm --filter @webstudio-is/builder test
app/builder/shared/asset-manager` — 126 tests passed
- `pnpm --filter @webstudio-is/builder typecheck`
- `pnpm lint`
- `pnpm check:package-boundaries`
- focused builder E2E: dragging auto-scrolls a long folder list
- focused builder E2E: multiselected assets move from the context menu

## Review note

The current validation prevents missing destinations and folder cycles.
A small follow-up is still needed to disable moves when every selected
item is already in the chosen destination, avoiding a no-op mutation and
announcement.
2026-07-18 01:40:23 +02:00
Oleg Isonen 878d6f1de1 feat: Add asset folders to asset manager and improve asset manager UX (#5892)
Closes https://github.com/webstudio-is/webstudio/issues/5877
Closes https://github.com/webstudio-is/webstudio/issues/4775


- Organize assets into nested folders.
- Navigate folders with breadcrumbs and Back controls.
- Select and manage multiple assets and folders at once.
- Drag, copy, cut, paste, duplicate, move, and delete items.
- Use context menus and familiar keyboard shortcuts for common actions.
- Search and sort assets and folders, with folders grouped first.
- Upload files directly into the active folder.
- Manage folder placement from asset and folder settings.
- Automate asset and folder management through MCP.
2026-07-17 23:39:14 +02:00
Oleg Isonen d440e02990 feat: Add safer MCP authoring and draft-page verification (#5905)
- **Restore points for agent work**: Create named restore points before
major edits, review changes with a dry run, and safely revert project
content if needed.

- **Shared Slot authoring**: Agents can turn existing sections into
shared Slots and insert linked copies across pages, including valid
nested Slots.

- **DTCG and Figma token imports**: Import design tokens and CSS
variables through CLI, MCP, or direct paste, with aliases, modes,
composite values, and mappings supported.

- **Consistent token conflict handling**: Every paste workflow now
offers the same preserve, rename, or merge choices instead of silently
overwriting existing design tokens.

- **Draft-page previews**: Agents can generate and inspect previews of
draft pages without publishing them or exposing drafts in production
builds.

- **Safer MCP mutations**: Destructive operations require explicit
confirmation, invalid raw patches and invented record IDs are rejected,
and restore operations commit atomically.

- **More dependable agent contracts**: New tools have complete runtime
schemas, clearer validation errors, and consistent behavior across CLI,
MCP, Builder, and server APIs.
2026-07-17 23:16:39 +02:00
Oleg Isonen 13c0351a03 fix: Move agent connection setup from Builder to the CLI (#5899)
## Summary

- remove the misleading **Connect your agent** section from Builder
Project Settings
- make the CLI the sole owner of MCP client configuration
- verify the linked project endpoint and credential before changing
client configuration
- safely merge Webstudio into existing Claude Code, Cursor, and VS Code
MCP files
- print the explicit global registration command for Codex instead of
editing its global configuration silently
- document the agent-led setup flow and safe handling of editable share
links

## Why

Builder runs in the browser and cannot configure files or global
settings on a user's local machine. The previous Project Settings UI
duplicated client definitions in the protocol package, exposed a setup
command containing the project credential, and could appear successful
without proving that the local agent was connected.

This moves local-client concerns into the CLI, removes the browser-only
setup surface, and makes configuration success depend on a valid,
reachable project link.

## User impact

A user can ask their agent to connect the current folder to Webstudio.
The agent links and synchronizes the project, runs `webstudio connect
<client>`, reloads the client, and verifies the connection by listing
project pages.

Invalid or stale links fail before any client file is changed, with a
credential-safe recovery message.

## Validation

- full CLI suite: 50 files, 786 tests
- full Builder suite: 163 files, 2,148 tests
- protocol suite: 73 tests
- CLI, Builder, and protocol typechecks
- root lint and package-boundary checks
- generated API and documentation checks
- real VS Code MCP handshake against a saved project: 156 tools
discovered
- fresh weak-model subagent test: repeated connection remained
idempotent and `meta.index` returned `ok: true`
2026-07-17 10:54:46 +02:00
Oleg Isonen 98d5c607ee feat: Improve MCP safety, context efficiency, and agent workflows (#5895)
## Summary

This combines the three reported MCP improvements into one release-ready
change:

- Safer mutation planning and confirmation for destructive operations.
- Much smaller MCP handshake and default discovery responses.
- Better agent workflows for checkpoints, multi-project work, and page
duplication.

## Safer destructive operations

- Exposes `dryRun` in MCP schemas for every local-capable mutation.
- Returns planned transactions through `meta.session.transaction`.
- Requires a two-step confirmation flow for destructive semantic
operations.
- Returns a short-lived token bound to the project, build version,
input, and exact generated patch plan.
- Rejects expired tokens, altered inputs, changed versions, and changed
plans.
- Sets `destructiveHint: true` only for operations that actually require
confirmation.
- Explicitly protects destructive operations whose names do not begin
with delete or replace, including replacing all redirects and clearing
all styles from a style source.

## Smaller, focused MCP context

- Defers oversized tool input schemas from the initial MCP handshake.
- Keeps complete focused schemas available through `meta.get_more_tools`
and CLI schema inspection.
- Makes template registry lists compact while preserving complete
payloads through focused get calls.
- Makes component summaries compact by default and supports paginated
component details.
- Replaces placeholder operation descriptions with useful command
descriptions.
- Constrains previously untyped JSON schema fields so clients can
validate inputs earlier.
- Keeps runtime output schemas compatible with strict MCP clients.

## Better agent workflows

- Allows read-only discovery and inspection while a workflow checkpoint
is awaiting acknowledgement.
- Continues blocking mutations until the checkpoint is acknowledged.
- Checks persisted checkpoints before every workflow call rather than
only the first call.
- Adds `--project` support so saved projects can be selected without
relinking the current directory.
- Isolates project sessions and checkpoints by selected project.
- Adds atomic `duplicate-page` substitutions for copied fixed text and
copied variable values.
- Prevents substitutions from modifying source content or global root
state.
- Rejects ambiguous or missing copied variables without leaving a
partial duplicate.

## Realistic agent verification

Minimal-context tests used a weak agent against the local packaged CLI
and stdio MCP:

- Planned a page deletion, stopped for explicit user confirmation,
committed the unchanged plan, and verified the page was absent.
- Tried to reuse a confirmation token with altered input; Webstudio
returned `DESTRUCTIVE_CONFIRMATION_INVALID` and preserved both pages.
- Verified compact handshake schemas and focused retrieval of the
complete oversized schema.
- Verified compact template and component discovery responses.
- Selected a saved project explicitly without relying on the directory
link.
- Verified checkpointed workflows permit reads but block mutations.
- Duplicated a London page into a Paris page with atomic text and
variable substitutions.
- Verified source content remained London, copied content became Paris,
and temporary pages were removed.

## Validation

- Project-build focused suites: 188 tests passed.
- CLI focused suites: 183 tests passed.
- Protocol focused suites: 21 tests passed.
- CLI, project-build, and protocol typechecks passed.
- Repository lint passed with zero warnings.
- Package-boundary validation passed.
- Generated runtime operation contracts were regenerated from source.
- Real local CLI/MCP tests passed against a running Builder server.

Closes #5887
Closes #5888
Closes #5889
2026-07-17 00:39:09 +02:00
Oleg Isonen 27eecd1a29 fix: remap conflicting pasted breakpoint ids (#5898)
## What changed

- Remap pasted breakpoint IDs when the same ID already belongs to a
different breakpoint in the destination project.
- Carry the remapped ID into pasted style declarations.
- Add a regression test for inserting a fragment whose breakpoint ID
conflicts with an existing project breakpoint.

## Why

HTML and Tailwind conversion uses compact fragment-local breakpoint IDs
such as `"0"` and `"1"`. In non-empty projects, one of those IDs can
already identify a different breakpoint. The fragment copy path
previously retained the incoming ID, causing the runtime to reject the
mutation with `Generated record id "1" already exists`.

## Impact

Pasting HTML with Tailwind classes now works in existing projects even
when generated fragment breakpoint IDs overlap project breakpoint IDs.
Matching breakpoints continue to be reused.

## Validation

- `pnpm --filter @webstudio-is/project-build test --
src/runtime/components.test.ts`
- `pnpm --filter @webstudio-is/project-build test --
src/runtime/fragment.test.tsx src/runtime/breakpoints.test.ts`
- `pnpm --filter @webstudio-is/project-build typecheck`
- `pnpm exec oxlint packages/project-build/src/runtime/fragment.ts
packages/project-build/src/runtime/components.test.ts`
- `pnpm exec oxfmt --check
packages/project-build/src/runtime/fragment.ts
packages/project-build/src/runtime/components.test.ts`
- `git diff --check`
2026-07-16 23:34:17 +02:00
Vianney MORAINandClaude Opus 4.8 b395556d7a fix: wait for db over TCP in dev/backend.sh to avoid false-positive readiness (#5891)
## Description

`builder_backend_wait_for_db` checks readiness by running `psql` inside
the `db` container, which connects over the **unix socket**. The
official `postgres` image's entrypoint starts a temporary server with
`listen_addresses=''` (socket only) while it runs its init phase. During
that window the socket probe succeeds, but host-side clients (prisma
migrate, postgrest) connecting over TCP still get `connection refused` .
so the wait can return before the database is actually reachable.

It's a timing race: it rarely bites with a fast init, but it's
reproducible with slower images/machines (we hit it consistently in our
fork's CI, which uses a pg image with a longer init phase).

Fix: make the readiness probe connect the same way real clients do. Over
TCP (`psql -h 127.0.0.1`). `PGPASSWORD` is needed because host
connections use password auth, unlike the socket which is `trust`.

Same one-line change to the probe in `builder_backend_wait_for_db`;
behavior is otherwise identical.

## Steps for reproduction

1. `docker compose down -v` in `apps/builder` (force a fresh initdb)
2. run `dev/run-local.sh` (or anything using
`builder_backend_wait_for_db`)
3. on a slow machine the wait returns during the init phase and the
following `prisma migrate` / postgrest startup fails with `connection
refused`; with this patch the wait only returns once TCP is accepting
connections

## Code Review

- [ ] hi @kof, I need you to do
  - detailed review (it's a one-line probe change in `dev/backend.sh`)

## Before requesting a review

- [x] made a self-review
- [x] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated test cases document n/a (dev tooling only)
- [ ] added tests -> n/a (shell dev script)
- [x] if any new env variables are added, added them to `.env` file ->
none added

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:15:34 +02:00
Oleg Isonen 12ad74584a feat: Improve MCP authoring, auditing, and verification (#5886)
## Summary

This improves how coding agents discover, author, verify, and audit
Webstudio projects through the CLI and MCP. The work focuses on making
agents more reliable with less context, while keeping edits semantic and
Builder-editable.

## What changes for users

- Agents can verify dynamic bindings after authoring and receive
actionable diagnostics when expressions, resources, scopes, or component
props do not line up.
- Agents can create complete resource-backed runtime UI through a
semantic operation instead of coordinating fragile low-level edits.
- MCP discovery and command output are compact by default, with
pagination and focused verbose detail when an agent needs more context.
- Asset, style, token, font, page, and component inspection provides
stronger usage context so agents can preserve the existing design
system.
- Rendered audits provide better evidence for responsive behavior,
geometry, contrast, generated-build size, and large-project runs.
- Cross-project MCP workflows can run from a manifest with explicit
mutation approval, isolated failures, resumable progress, and persistent
checkpoints.
- Project-specific agent onboarding is clearer and does not add
telemetry.
- Packaged CLI releases gain stronger smoke verification for install,
MCP startup, authoring, preview, screenshots, and audits.

## Reliability and architecture

- Runtime operation output schemas are generated from the runtime
registry and remain client-compatible.
- Project-build exports are consolidated around architectural boundaries
instead of feature-by-feature convenience entry points.
- HTTP, preview, screenshot, and project-session paths are hardened for
longer autonomous workflows.
- Craft compatibility work is read-only and provenance-aware; it does
not silently opt ordinary projects into Craft behavior.
- A minimal-context evaluation harness exercises key workflows with a
weaker model and stores bounded, privacy-safe evidence.

## Validation

- Rebased on the latest `origin/main`.
- `pnpm lint`
- Repository-wide `oxfmt --check`
- CLI typecheck and full test suite: 773 tests passed.
- Project-build typecheck and full test suite: 1,866 tests passed.
- Protocol typecheck and full test suite: 83 tests passed.
- HTTP client tests: 23 passed.
- CSS data tests: 3,620 passed, 1 skipped.
- Focused Builder tests: 67 passed.
- Package-boundary, generated API, and generated documentation checks
passed.
- Minimal-context agent evaluations passed for authenticated
resource-backed UI and design-system-aware responsive authoring.
2026-07-16 17:53:16 +02:00
Oleg Isonen d579607ed8 feat: Add draft pages (#5885)
Closes https://github.com/webstudio-is/webstudio/issues/3036

## Summary

- add an optional page-level draft state with a presentation-only
`[Draft]` prefix in Builder
- add **Mark as draft** and **Stage for publish** actions to the Page
details header menu
- keep drafts editable, previewable, linkable, duplicable, and
path-reserving in Builder
- exclude drafts from generated routes, public page collections, sitemap
output, staging, and production builds
- expose draft state and usage guidance through the runtime API, HTTP
client, CLI docs, and MCP contracts

## Why

Pages need a way to remain unfinished inside Builder without being
included in the next site deployment. Draft is an exclusion flag, not a
separate revision or publishing workflow state.

## Behavior and fixes

- home and `/*` catch-all pages cannot be drafts
- draft pages must be staged before becoming the home page
- restricted features used only on draft pages no longer block
publishing the publishable site
- **Stage for publish** only clears draft state; it does not deploy the
site
- missing or explicit `false` draft state remains backward-compatible
and publishable

## Validation

- 5,179 package tests passed across SDK, migrations, project-build, CLI,
and Builder
- targeted Builder browser E2E passed for draft/stage actions,
persistence, home-page guidance, copy, duplicate, delete, and
generated-app build behavior
- all affected package typechecks passed
- lint and package-boundary checks passed
- generated runtime contracts and CLI docs are reproducible
- `git diff --check` passed
2026-07-16 00:56:54 +02:00
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
Oleg Isonen 2808f06808 feat: Improve MCP validation errors with actionable guidance (#5881)
## What changed

- Return structured validation issues with stable codes, complete field
paths, constraints, and minimal correction examples.
- Preserve validation details through the Builder API, CLI, MCP, local
project sessions, and tRPC errors.
- Explain invalid expressions, JSX fragments, page selectors, component
inputs, asset updates, and project settings in terms an agent can act
on.
- Remove stack frames and credentials from parser details before
exposing them.
- Keep concise human-readable errors while making the complete
structured issues available to agents.

## Why

Agents previously received vague errors without enough information to
repair a request. They could repeat the same invalid call or require
manual intervention.

## User impact

CLI and MCP agents can now identify the exact invalid field, understand
the constraint, see a valid example, and retry with a corrected request.

## Validation

- Focused runtime, MCP, CLI, API, and tRPC validation tests.
- Structured error propagation tests across local and server execution.
- Typechecks and generated contract verification.
2026-07-15 11:33:36 +02:00
Oleg Isonen 03aeb535ef feat: Add semantic Collection authoring to MCP (#5880)
## What changed

- Add an `insert-collection` MCP and CLI operation for creating repeated
UI from array or object data.
- Create the Collection, iterable binding, current-item/current-key
parameters, repeated item structure, and descendant bindings atomically.
- Accept literal JSON data or expressions backed by project variables
and resource results.
- Support `collectionItem` and `collectionItemKey` expressions inside
the repeated Webstudio JSX item.
- Return the created Collection, item root, and parameter IDs for
immediate inspection and follow-up edits.
- Document when agents should use Collection for lists, grids, cards,
rows, options, tabs, and other repeated content.

## Why

Building a data-driven list previously required several low-level
operations and manual handling of Collection's internal parameters. A
missed step could leave a partially configured or incorrectly scoped
Collection.

## User impact

Agents can turn resource or variable data into a correctly bound
repeated layout in one operation, then inspect and refine the result
normally.

## Validation

- Real-world local CLI test created and rendered a three-product
Collection from project data.
- Tests cover literal arrays, objects, resource expressions, item/key
bindings, malformed fragments, ID conflicts, server execution, and
project-session behavior.
- 176 focused tests, project-build typecheck, and generated-doc checks
pass after rebasing onto current `main`.
2026-07-15 11:26:14 +02:00
Oleg Isonen dd99e49fbe fix: Preserve selection after instance deletion (#5879) 2026-07-15 10:35:51 +02:00
Oleg Isonen e57bd297f5 test: cover drag gestures in builder e2e (#5876) 2026-07-14 22:43:51 +02:00
Oleg Isonen d186d24501 feat: Improve MCP project audits, visual verification, and dynamic content authoring (#5874)
This update helps AI agents understand, audit, and visually verify
Webstudio projects more reliably. It also adds clearer guidance for
expressions, Collections, screenshots, and responsive rendered audits.

### Audit complete projects

- Run one `audit` command across accessibility, SEO, security, assets,
styles, and performance.
- Audit the whole project or focus on a specific page, scope, or
severity.
- Receive stable findings with locations, explanations, and recommended
fixes.
- Continue large result sets through pagination without repeating
general guidance.

### Audit the rendered website

- Build and inspect the generated website, rather than relying only on
stored project data.
- Check every static page at representative mobile, tablet, and desktop
widths.
- Use one suitable viewport inside each configured breakpoint range.
- Reuse the same browser and resize pages between captures for
substantially faster audits.
- Process multiple pages concurrently while keeping resource use
bounded.
- Supply concrete examples for dynamic routes such as blog posts.
- Review and confirm unusually large screenshot plans before they run.

### Find visual and performance problems

Rendered audits can detect:

- Horizontal page overflow.
- Broken images.
- Images loaded eagerly below the fold.
- Images that are much larger than their rendered size.
- Render-blocking resources.
- Legacy font formats.
- Pages that fail to load or redirect somewhere unexpected.
- Pages captured before their layout becomes stable.

Detailed screenshots, measurements, failures, and timing evidence are
saved locally for further inspection.

### Capture generated pages directly

- Capture a project route with `webstudio screenshot --path /route`.
- Automatically generate and start a temporary production-style preview.
- Stop the temporary preview after the screenshot is captured.
- Return navigation, responsive layout, and page-size evidence with JSON
output.
- Allow external image domains needed by the generated preview.

### Reuse generated previews

- Cache generated preview builds when the project has not changed.
- Reuse preview dependencies across regenerations.
- Keep preview dependencies isolated from the user’s project
dependencies.
- Surface preview build and startup failures with useful diagnostic
output.
- Include local project assets in generated previews.

### Author Collections correctly

- Explain when Collection is required for arrays and objects.
- Guide agents to bind the complete iterable instead of one item or the
response wrapper.
- Explain how Collection repeats its children for every entry.
- Explain current-item and current-key scope.
- Preserve Webstudio’s generated Collection parameters.
- Guide agents to use stable values for repeated interactive components.

### Write expressions with fewer mistakes

- Add a dedicated `webstudio://project/expressions` reference.
- Document expression scope, supported syntax, and supported methods.
- Explain how resources, variables, Collections, actions, and `system`
values are accessed.
- Distinguish fixed values from runtime expressions.
- Provide valid examples for text, props, resource URLs, headers, query
parameters, and bodies.
- Warn agents that valid syntax does not guarantee that runtime data has
the expected shape.

### Improve agent discovery

- Make Collection and expression workflows discoverable through
`meta.guide`.
- Return Collection-specific instructions through `components.get`.
- Point relevant command schemas to the expression reference.
- Keep detailed guidance available without placing it in every tool
response.

### Improve audit reliability

- Report which rendered captures passed, found issues, failed, or were
skipped.
- Distinguish planning, preview, capture, and cleanup failures.
- Include actionable retry instructions with rendered failures.
- Preserve completed evidence when part of an audit fails.
- Detect stale or conflicting preview servers more clearly.
- Support cancellation and bounded capture timeouts.

### Improve packaged CLI verification

- Add a release-shaped CLI smoke test.
- Install the packed CLI in an isolated temporary project.
- Fail on peer-dependency warning floods.
- Verify preview, screenshots, MCP calls, rendered audits, and generated
assets.
- Confirm that generic React Router previews do not include Docker-only
image dependencies.
- Keep CLI and MCP stdout machine-readable while progress remains on
stderr.

## User Impact

Agents can now audit a real rendered Webstudio site, inspect responsive
behavior, find concrete visual and performance problems, and provide
evidence for their conclusions. They also receive much clearer
instructions when turning API data into repeated content or writing
dynamic expressions.
2026-07-14 13:52:09 +02:00
Oleg Isonen 11114fe85d fix: allow dynamic JSON-LD values (#5873) 2026-07-13 21:54:45 +02:00
Oleg Isonen 7d781bdc86 fix: MCP fixes (#5870)
Improves CLI and MCP reliability across project synchronization, asset
editing, imports, audits, and clipboard workflows.

## Changes

- Keeps asset filename and description updates after session refresh.
- Prevents intermittent Immer patch errors during consecutive MCP
mutations.
- Prevents false edit conflicts caused by stale local session state.
- Preserves asset uploads without treating them as redundant metadata
updates.
- Exposes editable asset filenames consistently through MCP.
- Imports project assets correctly when copying projects between
environments.
- Supports refreshing partially available project snapshots.
- Keeps MCP operations working when optional project data is
unavailable.
- Produces clearer compatibility errors when the API and CLI versions
differ.
- Makes rendered audits more resilient when individual screenshots fail.
- Prevents rendered audits from hanging while starting browser captures.
- Handles denied clipboard permissions without uncaught browser errors.
- Improves copy and paste reliability for pages, components, styles, and
animations.

## Verification

- Asset uploader tests and typechecking pass.
- Focused asset workflow E2E passes.
- Complete E2E shard 1 passes.
- Realistic MCP subagent test confirms:
  - Asset filename and description persist after refresh.
  - Consecutive mutations work without manual refresh.
  - No Immer patch error occurs.
  - No false conflict occurs.
  - Original asset values can be restored successfully.
2026-07-13 02:32:27 +02:00
Oleg IsonenandClaude Fable 5 071a4d9a85 feat: MCP update 3 (#5864)
## Summary

This update adds new MCP and CLI capabilities for project auditing,
structured data, project-specific agent instructions, focused project
search, safer bulk editing, image descriptions, font discovery, visual
verification, and external registry inspection.

## New Capabilities

### Audit projects

- Run a single `audit` command across accessibility, SEO, security,
assets, styles, and performance.
- Limit an audit to selected scopes, pages, or severity levels.
- Receive stable findings with locations and suggested fixes.
- Run rendered audits across desktop, mobile, and Builder breakpoint
widths.
- Detect horizontal overflow, broken images, oversized images, eager
below-fold images, render-blocking resources, and legacy font formats.
- Identify unused assets, tokens, CSS variables, local styles, and
breakpoints.
- Identify duplicate token declarations.
- Detect accessibility issues involving names, labels, headings,
landmarks, IDs, keyboard focus, ARIA, iframes, and autoplaying media.
- Detect SEO issues involving titles, descriptions, language, social
images, and structured data.
- Detect unsafe new-tab links and write resources exposed during page
rendering.

### Search an entire project

- Search project text, labels, props, resources, assets, and styles
through `search-project`.
- Find relevant records without downloading and reparsing the full
project snapshot.
- Scope searches to the relevant project-data areas.

### Add validated JSON-LD

- Add structured data with a dedicated JSON-LD component.
- Place JSON-LD inside the page Head Slot.
- Edit JSON in a purpose-built code editor.
- Prevent structurally invalid JSON-LD from being saved.
- Validate Schema.org types, properties, and values.
- Find invalid, missing, unknown, deprecated, or incompatible structured
data through the SEO audit.
- Let agents discover the correct JSON-LD workflow without using page
custom metadata or a generic HTML embed.

### Configure project-specific agent instructions

- Add AI-agent instructions from the new **Agents** section in Project
Settings.
- Synchronize those instructions into a managed root `AGENTS.md`.
- Update or remove the managed file automatically during project sync.
- Protect existing user-owned `AGENTS.md` files from being overwritten.
- Share the instructions with authenticated CLI and MCP agents.
- Keep agent instructions out of publicly readable production bundles.

### Generate and manage image descriptions

- Audit image assets for missing descriptions.
- Let a vision-capable agent inspect each image in its rendered context.
- Save generated descriptions to multiple image assets in one operation.
- Mark images as intentionally decorative.
- Reuse the saved asset description wherever the image is used.
- Re-run the audit to verify that missing-description findings are
resolved.

### Perform bounded bulk replacements

- Replace matching literal text across selected pages with
`replace-text`.
- Replace matching fixed prop text with `replace-prop-text`.
- Replace matching resource names or URLs with `replace-resource-text`.
- Restrict replacements by page, instance, prop, resource, field, match
mode, and maximum change count.
- Leave dynamic expressions unchanged.

### Inspect element ancestry

- Return an element’s direct parent in instance listings.
- Request the complete ancestor chain when inspecting an element.
- Understand tree placement without rebuilding the instance hierarchy
from raw project data.

### Discover available fonts

- List uploaded font families through `list-fonts`.
- Discover available system font stacks.
- Inspect font family, style, weight, format, and associated asset
information before applying typography.

### Inspect external component registries

- Inspect a local or remote shadcn-style registry item.
- Read its description, files, dependencies, targets, and documentation.
- Receive an explicit Webstudio compatibility report.
- Inspect registry metadata without installing or executing external
code.

### Capture generated project routes directly

- Run `webstudio screenshot --path /route` against the configured
project.
- Generate a temporary production-style preview automatically.
- Capture the requested route.
- Stop the temporary preview after capture.
- Avoid manually building and starting a preview for a single
screenshot.

### Assert visual changes

- Add expected text to screenshot comparisons.
- Set maximum pixel mismatch limits.
- Set minimum or maximum changed-region counts.
- Assert whether overall brightness or a color channel moved in the
expected direction.
- Use these assertions as pass/fail evidence for visual changes.

### Require compatible CLI versions

- Send the project-bundle contract version with CLI synchronization
requests.
- Stop incompatible CLI versions before they receive incomplete project
data.
- Tell users exactly how to update the CLI or run the latest version
once.
- Prevent older clients from silently dropping project settings.

## Upgrade Note

This branch introduces a new synchronized project-bundle contract. Older
CLI versions must update before synchronizing against the new API.

```sh
npm install -g webstudio@latest
```

Or run the latest version once:

```sh
npx webstudio@latest <command>
```

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 11:27:58 +02:00
Oleg IsonenandClaude Fable 5 68b7458720 fix: restrict content mode text editing on canvas (#5866)
In content mode user should only edit what's inside a content block.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 02:18:44 +02:00
Oleg IsonenandClaude Fable 5 de23e2a888 chore: migrate toolchain to oxc (oxfmt, oxlint, rolldown-vite) and typeScript 7 (#5868)
## prettier -> oxfmt (0.58.0)

- .oxfmtrc.json generated with `oxfmt --migrate=prettier`: trailingComma
es5, printWidth 80 (oxfmt defaults to 100), sortPackageJson disabled,
.prettierignore patterns folded in (file deleted).
- ignorePatterns additionally exclude yml/yaml/toml/jsonc and
packages/cli/templates/** so oxfmt covers exactly the file set prettier
used to format (ts,tsx,js,json,css,md) and never touches user-facing
scaffolding artifacts.
- root `format` script, nano-staged pre-commit hook and the CI check
(`pnpm oxfmt --check`, replacing `prettier --cache --check` and its
actions/cache step — oxfmt checks the whole repo in ~0.7s) now run
oxfmt.
- every generator script that ran `prettier --write` on __generated__
output now runs `oxfmt` (css-data, icons, html-data, postgrest, sdk,
sdk-components-*, apps/builder tailwind preflight).
- the four scripts that used prettier's JS `format()` API write raw
source instead and their package.json scripts pipe the generated file
through the oxfmt CLI: project-build generate-docs +
generate-runtime-operation-contracts, cli generate-docs, apps/builder
generate-server-only-api-metadata. oxfmt rejects paths containing "..",
so cross-package generated files are formatted via a subshell cd into
the owning package.
- one-time reformat: oxfmt's canonical output differs from prettier on 8
repo source files (binary-operator continuation indent, import() call
wrapping, sub-pixel spacing of empty for-clauses); oxfmt honors existing
`// prettier-ignore` comments so intentional layouts are kept.
- prettier remains ONLY as a cli devDependency for the
prettier/standalone HTML normalizer inside html-to-jsx.test.ts, and
inside fixtures/ + packages/cli/templates/ (ships to scaffolded user
projects; out of scope here).
- editor config switched from esbenp.prettier-vscode to oxc.oxc-vscode
(devcontainer extension list, .vscode editor.defaultFormatter).

## oxlint 1.56 -> 1.73

- oxlint 1.73 rules-of-hooks special-cases hooks NAMED useEffectEvent:
their results may only be called from effects. Our
app/shared/hook-utils/effect-event.ts is a stable-callback helper
(useEvent pattern), intentionally called from event handlers and passed
as props. The rule is disabled via .oxlintrc.json overrides for the five
files doing this (product code untouched); note those files lose
hook-order linting entirely until the rule becomes configurable.

## TypeScript 5.8.2 -> 7.0.2 (native compiler)

- `tsc` is now the Go-based native binary; all `tsgo` script usages
(workspace packages and fixtures) renamed back to `tsc` and
@typescript/native-preview removed (the package is being phased out).
- fixes for TS7 changed defaults and stricter checks:
- `types` now defaults to [] -> base tsconfig sets "types": ["node"]
(restores the implicit-@types/node behavior of TS5).
- `rootDir` now defaults to ./ -> every tsconfig.dts.json sets
"rootDir": "./src" (TS5011 otherwise).
- import assertions removed -> cli/src/cli.ts uses `with { type: "json"
}` (TS2880).
- stricter isolatedDeclarations inference -> explicit annotations in
css-data bin/property-filter.ts (TS9010) and image image-dev.stories.tsx
(TS9013).
- declaration serialization limit -> project-build builder-runtime.ts
runtimeOperationContracts gets an explicit type (TS7056); the annotation
preserves the narrow RuntimeOperationId union.
- TS7 ships no stable programmatic API:
- react-sdk (component-generator tests drive the compiler API) aliases
its typescript devDependency to @typescript/typescript6@^6.0.2; its bin
is `tsc6`, so the package's typecheck still runs native TS7 tsc from the
workspace root.
- generate-arg-types keeps typescript 5.8.2 for react-docgen-typescript.
- fixtures/ and packages/cli/templates/ keep typescript 5.8.2
(user-facing); fixture scripts still work because plain `tsc` resolves
to their local dependency.

## vite -> rolldown-vite 7.3.1 (oxc bundler)

- global pnpm override `"vite": "npm:rolldown-vite@^7.3.1"`: the builder
app (remix v2 vite plugin works unmodified), every package vite build
and the storybook build now bundle on rolldown/oxc.
- vitest is scoped BACK to vanilla vite via `vitest>vite`,
`vite-node>vite` and `@vitest/mocker>vite` overrides because vitest
3.1's runner does not understand rolldown's SSR transform
(__vite_ssr_exportName__ ReferenceError in every suite).
- those overrides pin vite EXACTLY to 6.3.4: letting ^6.3.4 float to
6.4.3 breaks cli prebuild tests (dynamic import of a generated
app/routes/$.tsx fails to resolve under 6.4.3's loader).

## unrelated cleanup requested during review

- apps/builder commands.ts imports duplicate-tokens-group statically
instead of via dynamic import. The circular dependency the dynamic
import guarded against only exists through the command-panel barrel
(command-panel.tsx > groups/index.ts > commands-group.tsx >
commands.ts); importing the group module directly is cycle-free
(verified with madge), matching the neighboring wrap-group and
convert-group imports.

## verification

- pnpm lint, oxfmt --check: clean.
- pnpm -r typecheck (TS7 native) and pnpm dts: clean.
- pnpm -r test: all suites pass (builder 2093 tests, cli 630, react-sdk
45, project-build 11, ...).
- builder app build, full workspace build, cli build and storybook build
all succeed on rolldown-vite.

## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 01:03:36 +02:00
Oleg Isonen 6983ecfdb0 fix: Document MCP consumer capabilities & more fixes (#5862) 2026-07-10 16:00:54 +02:00
Oleg Isonen 6e10ae3809 fix: Fix Builder paste transfer data handling and publish sync edge cases (#5861)
- Fix publish sync for empty JSON data variables
- Retry transient asset downloads once with shared sync-client backoff
- Fix Builder paste handling for Webstudio transfer data
- Add transfer/data-envelope terminology and colocated runtime
data-format modules
- Rename page clipboard runtime operation to page transfer semantics
- Report malformed Webstudio/Webflow paste data through paste results
instead of inserting it as text
- Add browser-level E2E coverage for instance, page, folder, template,
generic plugin, malformed data, native input, and content-mode paste
flows

## Details

- Allows empty JSON data variables to sync/publish correctly.
- Adds asset download retry coverage and uses shared backoff logic.
- Introduces runtime `data-formats` modules for data envelopes, instance
transfer data, and page transfer data.
- Removes stale clipboard aliases and `validateTemplateStructure`.
- Keeps clipboard as a Builder UI transport concern while
runtime/protocol use transfer-data terminology.
- Changes paste plugins to return expressive success/error results so
callers can show toast errors and stop fallback insertion.
- Prevents malformed Webstudio transfer payloads from falling through to
text/HTML/markdown insertion.
- Handles malformed Webflow-owned paste data without throwing.
- Adds shared copy-paste fragment insertion helpers to reduce duplicated
breakpoint-warning/fragment-data logic.
2026-07-10 13:51:55 +02:00
Oleg Isonen d291e4b671 feat: Builder api runtime contracts guardrails for MCP (#5857)
This PR expands Webstudio MCP and CLI into a more complete agent
authoring interface. Agents can discover project capabilities, edit real
Webstudio content, use data/resources, verify visual output, and report
useful issues when workflows fail.

## MCP User Capabilities

- Create, update, duplicate, reorder, and delete pages.
- Create pages from templates and manage reusable page templates.
- Inspect project pages, instances, props, styles, assets, variables,
resources, and metadata.
- Insert Webstudio components and authored JSX fragments into pages.
- Edit text, props, styles, breakpoints, design tokens, and CSS
variables.
- Update page metadata, SEO fields, redirects, marketplace metadata, and
project settings.
- Create and use static data variables.
- Create and use dynamic resources fetched over HTTP.
- Use REST, GraphQL, and built-in system resources in authored pages.
- Bind data variables and resources to visible page content.
- Create resource-backed pages such as sitemap XML, structured SEO data,
and API-driven content sections.
- Preview current project state without requiring a publish step.
- Capture screenshots for visual verification.
- Verify responsive designs across desktop, tablet, and mobile
breakpoints.
- Use screenshot diff and OCR-style checks to inspect rendered output.
- Reset and refresh local MCP project state when needed.
- Discover available CLI/MCP commands from generated manuals.
- Use clearer examples for resources, data variables, JSX authoring,
previewing, and visual checks.
- Read marketplace product metadata without requiring a full project
snapshot.
- Get safer guidance when using low-level patch tools.
- Get a ready-to-copy Discord report template when MCP/CLI behavior is
confusing or broken.
2026-07-10 02:13:22 +02:00