mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-03 02:27:57 +09:00
0.292.0
27
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5a57234c75 |
revert: Store Content Block content in MDX assets
Revert the accidental merge of #6125 so the implementation can continue in draft PR #6181. |
||
|
|
5ec3547d36 |
fix: Support JSON content files in Builder (#6168)
## Summary - make the complete asset filename editable in Asset settings - convert existing editable text assets when their extension changes while preserving the asset ID - accept every JSON root type and normalize JSON-compatible syntax into formatted strict JSON - expose the same optional extension change through MCP/API `update-asset-content` - initialize new JSON files and empty text-to-JSON conversions with a valid empty object - distinguish browser URL imports from JSON file uploads so JSON objects with a root `url` field remain file content - update the Assets and Content Engine documentation ## Root cause Asset settings rendered the extension as a fixed suffix outside the name input. The metadata rename mutation could only change the display basename, while content revisions always inherited the current storage extension. As a result, changing `.md` to `.json` was impossible in the UI and unavailable through the shared MCP/API revision command. Asset settings now edits the complete filename. Ordinary renames keep using the metadata mutation. A text-extension change loads the current content, validates it for the target format, and writes a new immutable revision through the existing conflict-safe content endpoint. The existing Acorn-backed `parseJsonExpression` utility accepts JSON-compatible syntax without evaluating code and serializes it as strict JSON. Objects, arrays, strings, numbers, booleans, and `null` are all accepted. ## Checklist - [x] Create JSON files by entering a `.json` filename - [x] Edit the complete filename in Asset settings - [x] Convert editable text-file extensions while preserving the asset ID - [x] Expose extension conversion through `update-asset-content` - [x] Create JSON files and convert empty text files with a valid empty object - [x] Normalize safe JSON-compatible syntax to strict JSON - [x] Accept objects, arrays, and scalar JSON roots - [x] Reject executable or incomplete content - [x] Preserve browser-uploaded JSON object shapes - [x] Review and update authoritative Builder documentation - [x] Add focused UI, revision, HTTP-client, CLI/MCP, protocol, and upload regression tests - [x] Run affected typechecks, lint, documentation checks, and the Builder production build - [ ] Manually verify create, edit, rename `.md` to `.json`, reload persistence, and Content Engine query in a browser - [ ] Run the complete local agent evaluation suite if approved ## Verification - 217 focused tests passed across Builder, asset revisions, HTTP client, CLI/MCP, and protocol - Builder, asset-uploader, HTTP-client, protocol, CLI, and project-build typechecks passed - Builder production build passed - MCP and Content Engine documentation checks passed - `oxlint` on changed TypeScript files passed - `git diff --check` passed - Regression tests were demonstrated failing before the implementation and passing afterward A disposable E2E database and PostgREST stack bootstrapped successfully in the earlier real-path test, but UI automation remained blocked because no controllable browser was available. Fixture inputs and generated fixture outputs are not affected. Agent evaluations were not run because approval is required and was not requested. Closes #6167 |
||
|
|
81d5148046 |
fix: canonicalize trailing-slash page URLs (#6173)
## Outcome Canonical page URLs now omit a trailing slash in Webstudio Cloud sites and exported JavaScript applications. A request such as `/about/?campaign=launch` receives a permanent `301` redirect to `/about?campaign=launch`, preventing both URL variants from serving identical page content. The behavior is implemented once in the generated root redirect handler, so it covers fixed and dynamic application routes without generating an extra route per page. Exact project redirects remain authoritative. Protocol-relative-looking paths such as `//example.com/` are left untouched so canonicalization cannot become an external redirect. Static exports cannot redirect requests themselves. Their URL behavior remains host-specific and is documented for Cloudflare Pages, Netlify, Vercel, and other static hosts. ## Implementation - Add one shared pathname normalizer in the SDK. - Apply canonicalization after exact authored redirect matching in both generated application runtimes. - Ignore repeated leading slashes before constructing a redirect location. - Extend redirect-loop detection to model the implicit canonical redirect. - Regenerate the affected fixture applications from their templates. - Document application canonicalization and host-specific static export behavior. ## Todo 1. [x] Add central trailing-slash canonicalization. 2. [x] Preserve query strings, encoded path segments, and the root path. 3. [x] Cover concrete dynamic URLs without per-route generation. 4. [x] Preserve explicit project redirect precedence. 5. [x] Detect redirect loops that pass through canonicalization. 6. [x] Prevent protocol-relative external redirects. 7. [x] Regenerate and review fixture output. 8. [x] Review documentation impact; document application and SSG behavior. 9. [x] Run targeted and repository-level verification. ## Verification - SDK tests: 548 passed - SDK typecheck: passed - Project Build tests: 2,379 passed - Project Build typecheck: passed - CLI tests: 997 passed; two tests timed out only while three package suites ran concurrently, then both affected files passed in isolation (6/6) - Redirect regression suite after security follow-up: 302 passed - CLI typecheck: passed - `pnpm lint`: passed - `pnpm check:package-boundaries`: passed - `pnpm fixtures`: passed - Documentation internal anchors and Markdown whitespace: checked - New regression tests were confirmed failing before their implementations and passing afterward - Agent evaluations were not run because they require separate explicit approval Closes #6172 Closes https://github.com/webstudio-is/webstudio/issues/4327 |
||
|
|
86b6310fff | feat: Store Content Block content in MDX assets | ||
|
|
af11ec211f |
feat: Search all local project data from MCP (#6165)
Ref #6154 ## What - Add standalone search across all 13 synchronized Builder namespaces. - Search in the CLI ProjectSession and send only paged matches to the model; initial synchronization is unchanged. - Return stable match ids, exact paths, entities, references, and affected routes. - Preserve deprecated `scopes` output, redact recognized credential fields, and document the command. ## Objectives - [x] O1 — Universal Builder namespace search - [x] O2 — Stable identity and actionable location - [x] O3 — Filters, pagination, route impact, and references - [x] O4 — Honest synchronization → local search → model-input boundary - [x] O5 — Standalone command and workflow documentation - [x] O6 — Safety, compatibility, typed contracts, and regression tests Verified by Atlas (implementation), Scribe (docs/workflow), and Sentinel (adversarial review). ## Remaining #6154 work - [ ] Atomic semantic multi-record updates - [ ] Targeted route rendering and assertions - [ ] General slow-operation consent and time budgets - [ ] Full agent evaluation suite after approval ## Verification - Project search + MCP: 129 tests passed - Protocol docs: 8 tests passed - CLI schema/docs: 23 tests passed - Compact MCP handshake budget test passed - Project-build, protocol, and CLI typechecks passed - Generated docs and API checks passed - Agent evaluations not run; approval is required ## Limitation Asset metadata is searchable. Asset binaries and document contents are not Builder namespace data and are not searched. |
||
|
|
dbfb0a9849 |
fix: Preserve variable font styles (#6153)
## Summary Preserve font style metadata for variable fonts so upright and italic files from the same family produce distinct `@font-face` rules. Variable fonts with an `ital` or `slnt` axis are also registered for the matching CSS styles. ## Technical choices - Detect `normal`, `italic`, and `oblique` from the font binary, preferring OS/2 `fsSelection`, then `post.italicAngle`, then the existing subfamily parser. - Add `style` to variable-font metadata while defaulting legacy stored records to `normal`. - Keep update metadata partial and strict, but accept and persist `style` and `variationAxes` together so a `get-asset` result can be written back. - Group generated font faces by family, style, and browser-selectable variable descriptors so separate upright and italic files cannot overwrite each other. - Regenerate the runtime operation contracts from the updated schema. ## Checklist - [x] Add regressions using real upright and italic Inter variable-font binaries. - [x] Cover style detection, metadata compatibility, updates, and generated font-face selection. - [x] Verify the final stylesheet contains distinct upright and italic `@font-face` rules. - [x] Verify the public asset update contract accepts a complete variable-font metadata object. - [x] Review documentation impact and update the custom-font guide. - [x] Regenerate and verify runtime API contracts. ## Verification - `@webstudio-is/fonts`: 14 tests and typecheck passed. - `@webstudio-is/asset-uploader`: 198 tests and typecheck passed. - `@webstudio-is/sdk`: 514 tests and typecheck passed. - `@webstudio-is/project-build`: 2,094 tests and typecheck passed. - CLI: 980 tests and typecheck passed. - Builder typecheck passed. - `pnpm lint`, `pnpm check:package-boundaries`, `pnpm check:generated-api`, and `pnpm check:generated-docs` passed. - Regression tests were demonstrated failing against the previous behavior and passing with the fix. - Fixture builds regenerated successfully with no diff. Full remote fixture sync was attempted, but the deployed API rejected the source CLI contract as incompatible. - Agent evaluations were not run because they require separate explicit approval. Closes #6150 |
||
|
|
a22b23936d |
docs: Explain Content Engine limits (#6123)
## Summary - explain which kinds of blogs, catalogues, directories, and file-based content fit the Content Engine - identify projects better served by an external CMS, commerce backend, or media service - translate the current query, database, and content-loading limits into practical guidance - link readers to the complete Content Engine limits reference ## Why The existing guide explains how to build a Markdown blog but does not help readers decide whether the Content Engine is appropriate for their content volume, media needs, or editorial workflow. This addition sets expectations before readers commit to an architecture. ## Todo - [x] Document suitable Content Engine use cases. - [x] Document cases that should use an external system. - [x] Confirm every stated limit against the current implementation and generated reference. - [x] Review documentation impact: the authoritative Content Engine guide is updated; navigation is unchanged because this is an existing page. - [x] Verify the reference link and anchor. ## Verification - `pnpm docs:content-engine:test` — passed - `pnpm docs:content-engine:check` — generated files are clean - verified `content-engine-reference.md#query-limits` exists - `git diff --check` — passed The repository pre-commit hook was bypassed after its `oxfmt` task rejected the docs-only target because `docs/` is excluded from that formatter. The hook restored the file unchanged; the documentation-specific checks above passed before committing. |
||
|
|
87968f40ff |
fix: Improve MCP authoring and preview reliability (#6105)
## Summary
Fix MCP reliability failures reported in ten issues against CLI 0.288.0
and 0.289.0:
- keep every advertised array input schema client-valid, including
compact and tuple schemas
- report a text asset update as successful when its persisted revision
and bytes confirm that the server committed despite a failed response
- preserve standard package import resolution in generated React Router
previews
- upload variable WOFF2 fonts when callers provide the documented static
font metadata shape
- explain unmatched JSX as a stateless fragment syntax error
- distinguish the `animation` component namespace from value helpers and
reject unsupported CSS at-rules with an actionable validation error
- forward optional session tools such as `download-asset` through
top-level CLI shortcuts
- isolate published generated-preview dependencies from parent
workspaces
- return structured screenshot failures when React Router production
builds fail
Sensitive visual regression checks also run automatically for
organization-authored fork PRs. External fork PRs remain gated by
`safe-to-deploy`.
## Root causes and implementation
The MCP handshake compactor retained an array's type but discarded its
`items` schema. Unconstrained and tuple arrays could also be advertised
without `items`. Schema normalization now adds `items: {}` whenever an
array omits it, while focused discovery retains complete constraints.
Catalog coverage rejects every missing array item, including tuple
schemas, and the handshake remains below its 200 KB budget.
Asset content updates previously treated any failed response as a failed
mutation, even when the server had already swapped the revision.
Recovery now reads the current revision, compares the persisted bytes,
and confirms the revision remains stable across the read. It returns the
updated asset only when all evidence agrees. Otherwise it returns
`ASSET_UPDATE_COMMIT_UNCERTAIN` with guidance not to retry blindly.
Definitive 4xx responses retain their original errors.
The generated React Router Vite config replaced the client and SSR
resolver condition lists without explicitly retaining the standard
`import` condition. Both lists now preserve `import`. The regression
test generates a dynamic route, stages the built React Router SDK as a
published dependency without the local `webstudio` source condition, and
runs the generated build.
Variable fonts are detected with `variationAxes`. Merging the documented
static `style` and `weight` upload metadata into that detected variable
shape made validation fail after the binary was read. Font override
validation and shape-aware merging now live in `@webstudio-is/fonts`.
The SDK delegates to that domain function, which validates the complete
override before applying compatible fields, retains the detected
static-or-variable shape, and keeps the detected format.
Fragment parsing is stateless. Unmatched opening and closing tags now
explain that every opening element must use the same closing tag or be
self-closing, and that refreshing the session cannot repair malformed
JSX.
The `animation` binding is a component namespace, not a callable helper.
Tool schema text, evaluation errors, and the MCP manual now separate
component namespaces from value helpers. The MCP JSX `css` binding
parses the final interpolated CSS with CSS-tree and recursively rejects
selectors and unsupported at-rules such as `@keyframes`, while
preserving supported declarations and case-insensitive `@media` rules.
Keeping this validation at the external binding avoids changing internal
component templates.
CLI shortcut discovery previously omitted optional session tools even
though the runtime registered their handlers. Shortcut discovery now
includes the same optional tool categories as the CLI MCP host, while
real top-level CLI commands keep precedence.
Published generated previews could reuse a stale `node_modules` symlink
into a parent source workspace. Only development manifests containing
the local placeholder version may now reuse the CLI dependency tree.
Published manifests replace symlinks with a local install and disable
npm workspace discovery.
React Router could report a bundler failure while its build command
exited successfully outside CI, allowing screenshot startup to terminate
without a structured result. Managed production builds now set `CI=1`,
so the existing MCP error boundary receives the nonzero build failure
and prints structured JSON.
Visual regression authorization now distinguishes repository members
from external contributors. Organization members' fork PRs run on open,
synchronize, and reopen events; external fork code runs only from a
`safe-to-deploy` label event, and a later commit does not reuse that
approval.
## Implementation checklist
- [x] Preserve valid array item schemas in compact MCP discovery
- [x] Normalize tuple input schemas with an `items` fallback
- [x] Keep the MCP handshake below its 200 KB size budget
- [x] Cover the real `update-props` schema and oversized array
compaction
- [x] Reconcile failed asset-update responses against stable persisted
content
- [x] Reject recovery when a concurrent asset revision is detected
- [x] Preserve `import` resolution in generated React Router client and
SSR builds
- [x] Build a generated dynamic route against a staged published SDK
package
- [x] Regenerate and verify affected React Router fixtures
- [x] Preserve detected variable-font axes with documented upload
metadata
- [x] Add actionable unmatched-tag and unsupported-CSS validation
- [x] Correct animation namespace guidance in tool discovery and errors
- [x] Forward optional session tools through top-level CLI shortcuts
- [x] Replace parent-workspace dependency links for published previews
- [x] Disable npm workspace discovery for isolated preview installs
- [x] Make React Router build failures return nonzero in managed
previews
- [x] Run visual regression automatically for organization-authored PRs
- [x] Verify each regression test fails without its corresponding fix
- [x] Review documentation impact and update the authoritative MCP
manual plus generated outputs
- [x] Confirm no database migration or compatibility migration is
required
- [ ] Run `pnpm evaluations` after explicit approval; not run because
repository policy requires approval before agent evaluations
## Verification
- `packages/cli/src/prebuild.test.ts`: 57 tests passed
- `packages/cli/src/commands/schema.test.ts` and `mcp.test.ts`: 51 tests
passed
- `packages/project-build/src/runtime/components.test.ts` and
`mcp.test.ts`: 194 tests passed
- `packages/asset-uploader`: 196 tests passed
- focused font schema, SDK asset schema, CSS parser, and template CSS
tests passed
- `packages/http-client/src/index.test.ts`: 38 tests passed
- relevant CLI, project-build, asset-uploader, fonts, SDK, CSS data,
template, HTTP client, and React Router SDK typechecks passed
- MCP documentation tests, typecheck, generation, and Markdown source
tests passed
- React Router SDK package build passed
- full fixture link, sync, and generation pipeline passed
- affected Docker and Vercel fixture typechecks and locally bootstrapped
production builds passed
- complete CLI suite: 61 test files and 966 tests passed
- CLI typecheck passed
- preserved nested-workspace dynamic preview installed local `0.289.0`
dependencies and completed its production build
- visual-regression workflow YAML parsing and authorization truth table
passed
- repository lint passed with warnings denied
- formatting and `git diff --check` passed
## Tradeoffs and limitations
Deferred array schemas advertise unconstrained `items` in the compact
handshake to remain client-valid without duplicating detailed
constraints. Agents can retrieve the complete item schema through
focused `meta.get-more-tools` discovery.
Asset reconciliation performs three read requests only after an
uncertain 5xx, malformed response, or transport failure. This keeps the
normal successful path unchanged and avoids claiming success if the
revision changes during recovery.
For variable fonts, detected axes define the metadata shape. Static
`style` and `weight` hints are ignored because they cannot be
represented alongside `variationAxes`; compatible fields such as
`family` still override detection.
Native CSS keyframe authoring remains unsupported in fragment `css`
templates. The tool now rejects it before rendering and directs callers
to editable Webstudio Animation components instead of advertising a
nonexistent callable helper.
Published previews perform one isolated npm install when no valid local
dependency tree is cached. Local source development keeps the fast
workspace symlink path for placeholder-version manifests.
Closes #6104
Closes #6099
Closes #6098
Closes #6106
Closes #6107
Closes #6108
Closes #6114
Closes #6115
Closes #6116
Closes #6117
|
||
|
|
5c6ffd3148 |
docs: document Content Engine workflows (#6097)
## Summary - add a step-by-step Content Engine guide for building a Markdown article overview and dynamic article page - clarify that the example folder structure is optional and link to the Markdown Blog marketplace template - explain that an AI agent can complete the entire workflow through Webstudio MCP and include a ready-to-use prompt - document frontmatter, JSON files, relative and published asset paths, document references, draft filtering, and single-result resources - document Markdown-to-Markdown, Markdown-to-JSON, JSON-to-Markdown, and JSON-to-JSON document references, including fragments and JSON Pointer escaping - add a schema-aware `webstudio man content-engine` reference for fields, operators, saved and preview inputs, result/output/content modes, diagnostics, limits, and reference syntax - generate the GitBook Content Engine reference and the matching MCP manual section from that shared CLI source - fail documentation generation when result modes, output modes, content modes, diagnostic fields, or Content Engine limits drift from the implementation - add four focused visual-editor screenshots - keep the Assets page focused on asset management and link it to the dedicated Content Engine guide - update MCP Assets examples and the Markdown blog recipe to use Markdown files, `result: "one"`, direct detail bindings, page metadata, and visual verification ## Impact Users get one workflow for treating files as the source of truth while designing article listings and detail pages in Webstudio. The generated reference documents the complete Assets query contract and document-reference system. Agents receive the same reference through the MCP manual, so the product and agent documentation no longer need separate factual copies. This does not change product runtime behavior. ## Checklist - [x] Documentation impact reviewed - [x] Added the Content Engine guide and generated reference to `docs/SUMMARY.md` - [x] Updated related Assets, Data variables, and MCP documentation - [x] Verified internal documentation and image targets - [x] Verified the Markdown Blog marketplace URL returns HTTP 200 - [x] Confirmed the MCP recipe test failed before the recipe correction and passed afterward - [x] Confirmed the schema-coverage test fails when an implemented result mode is omitted and passes after restoration - [x] Confirmed both Content Engine generator tests fail without their corresponding generator behavior and pass after restoration - [x] Ran `pnpm --filter @webstudio-is/project-build test -- src/mcp.test.ts` - [x] Ran `pnpm --filter webstudio test -- src/commands/api-command-docs.test.ts` - [x] Ran the Content Engine and MCP generator tests - [x] Ran project-build and CLI typechecks - [x] Ran `pnpm check:package-boundaries` - [x] Ran targeted lint and formatting checks - [x] Ran `pnpm check:generated-docs` - [x] Verified the final diff and working tree - [ ] Agent evaluation suite: not run because it requires explicit approval Ref #5973 |
||
|
|
43a9f824ad |
fix: Resolve published asset paths in structured content (#6096)
## Summary Resolve Markdown frontmatter and JSON values written as published paths such as `./assets/hero.png` or `/assets/hero.png`, even when the content document and asset live in sibling Asset folders. This staging PR replaces #6094 and supersedes #6016. #6016's raw-format changes were unrelated to the reported asset-path problem. ## Technical approach - Keep format-neutral path indexing and resolution in `asset-path-resolution.ts`. - Keep `markdown-assets.ts` limited to Markdown destination parsing. - Normalize both Markdown frontmatter and JSON objects through the shared structured-value reference pipeline. - Keep canonical source-relative resolution as the first choice. - Recognize only the published `assets/<file-name>` path shape as a fallback. - Match the final canonical asset file name only when it uniquely identifies one project asset. - Leave external URLs, missing assets, ambiguous names, and unrelated root-relative paths unchanged. - Resolve recorded asset references to runtime URLs when queries render their results. ## Compatibility This extends resolution for imported/published structured content without changing ordinary source-relative paths or direct asset ID references. Duplicate final file names intentionally remain unresolved to avoid choosing the wrong asset. ## Checklist - [x] Add regression coverage for relative and root-relative published asset paths. - [x] Cover discovery and runtime structured-value resolution. - [x] Add explicit JSON document coverage with the asset in a sibling folder. - [x] Verify ambiguous asset names remain unresolved. - [x] Separate format-neutral resolution from Markdown parsing. - [x] Run the full content-engine test suite. - [x] Run content-engine typecheck and targeted lint/format checks. - [x] Rebuild content runtime and repository fixtures. - [x] Review documentation impact and update the Assets guide. - [ ] Manually verify the published site from `md-assets.staging`. - [ ] Confirm CI checks pass. ## Verification - Regression tests were run with the published-path fallback disabled and failed for both generic structured values and the explicit JSON integration case. - `pnpm --filter @webstudio-is/content-engine test` — 294 tests passed. - `pnpm --filter @webstudio-is/content-engine typecheck` — passed. - `pnpm exec oxlint --deny-warnings ...` — passed. - `pnpm exec oxfmt --check ...` — passed. - `pnpm --filter webstudio build:content-runtime` — passed. - `pnpm -r fixtures:build` — passed; no generated fixture diff. - `git diff --check` — passed. - Agent evaluations were not run because they require separate explicit approval. Closes #6093 |
||
|
|
eb46abf4e5 |
fix: Recover missing preview assets (#6091)
## Summary Fix session-based generated preview startup when the local `.webstudio/assets` directory has not been created yet. - materialize the current session's asset files before compiling the Assets resource index - reuse the existing safe asset downloader so missing parent directories are created and downloads retain retry and temporary-file cleanup behavior - return the stable `PREVIEW_ASSET_DOWNLOAD_FAILED` code with a concrete recovery action when asset access cannot be restored automatically - document the automatic recovery and regenerate the authoritative MCP manual ## Root cause `preview.start` materialized current ProjectSession data and compiled reachable Assets resources before generated-app prebuild. That compilation called `realpath` on the local assets directory, but the session path had never downloaded assets the way `webstudio sync` does. A newly linked project without `.webstudio/assets` therefore failed with `ENOENT` before preview generation. ## Technical choices - Download only after confirming that the project has a reachable Assets resource compilation plan. - Keep canonical path and symlink validation in the filesystem content source after materialization. - Wrap download failures at the preview boundary without exposing local paths or raw remote diagnostics. - Preserve the existing generated-doc source/generator workflow rather than editing generated guidance alone. ## Todo - [x] Reproduce startup from a missing local assets directory - [x] Materialize required session assets before index compilation - [x] Add actionable failure recovery - [x] Add fail/pass regression coverage - [x] Review documentation impact and update the MCP vision guidance - [x] Regenerate the CLI and GitBook MCP manuals - [x] Review fixture impact — no fixture inputs or generated fixture outputs are affected - [x] Run the focused low-reasoning Markdown fixture, including the cold assets-directory scenario - [ ] Deferred: run the remaining agent evaluation fixtures ## Verification - Regression demonstrated failing before the fix with `ENOENT` for the missing assets directory, then passing after the fix. - Recovery regression demonstrated failing with raw `ENOENT`, then passing with `PREVIEW_ASSET_DOWNLOAD_FAILED` and the retry action. - `pnpm --filter webstudio test` — 60 files, 976 tests passed. - `pnpm --filter webstudio exec vitest run src/project-session.test.ts src/mcp-guidance.test.ts` — 25 tests passed after final fixture cleanup. - `pnpm --filter webstudio typecheck` — passed. - Targeted `oxlint --deny-warnings` — passed. - Documentation generation, docs tests, and docs typecheck — passed. The aggregate generated-doc clean-tree guard reports the intentionally changed generated CLI/GitBook outputs included in this PR. - `git diff --check` — passed. - Focused real-world evaluation: `gpt-5.4-mini` with `model_reasoning_effort="low"`, `markdown-blog-v1`, 12/12 MCP calls succeeded, 0 failures, 0 retries, 2 rendered verifications, and all fixture checks passed. - Cold-directory variant: removed `.webstudio/assets` immediately before the first rendered verification; preview restored the required assets, and both verification calls plus content-database checks passed. - Remaining high-impact fixtures were not run; this was the targeted real-world scenario requested for #6090. ## Known limitations Preview startup still requires network and project asset access when required files are not already local. It now reports a stable error and tells the caller to restore access and retry instead of leaking an `ENOENT`. Closes #6090 |
||
|
|
db3b11970f |
fix: Optimize images in Markdown Embed (#6089)
## Summary Markdown Embed now renders image tags with the same optimized attributes and canvas behavior as the SDK Image component. The implementation shares the complete attribute-resolution path without rendering React inside the Markdown pipeline: - `@webstudio-is/image` exposes one framework-independent `getImageAttributes` function for optimization, placeholder fallback, loading, decoding, dimensions, alternative text, and responsive sources. - React-only element props such as `className`, `style`, handlers, context, and refs stay in React callers. - The SDK Image component and Markdown renderer both use `getSdkImageProps` for canvas-specific loading, decoding, asset identity, and incomplete-upload handling. - Markdown retains only the necessary HTML attribute-name conversion, sanitization, and Safari-safe `sizes` / `srcset` / `src` ordering. - The redundant low-level React Image primitive was removed. Its callers now render native `img` elements, and the image package no longer has React runtime or peer dependencies. ## Compatibility and tradeoffs - The SDK Image component remains the public React component because it owns React context and ref forwarding. - The removed low-level `@webstudio-is/image` Image export is replaced by the pure attribute function for internal callers. - No data migration or schema change is required. - Loader output is sanitized after transformation, while unsafe input URLs are sanitized before reaching the loader. ## Todo - [x] Share image attribute resolution between native, SDK, and Markdown images. - [x] Preserve SDK canvas behavior for Markdown images. - [x] Preserve safe URL sanitization and Safari-safe responsive attribute ordering. - [x] Remove the redundant low-level React image primitive and migrate its callers. - [x] Remove the overlapping `getImageProps` abstraction. - [x] Add regression coverage comparing Markdown, SDK Image, and native attribute output. - [x] Review documentation impact and update the Markdown Embed documentation. - [x] Run targeted tests, typechecks, builds, lint, formatting, package-boundary checks, and fixture generation. ## Verification - `pnpm --filter @webstudio-is/image test` - `pnpm --filter @webstudio-is/image typecheck` - `pnpm --filter @webstudio-is/image build` - `pnpm --filter @webstudio-is/image dts` - `pnpm --filter @webstudio-is/sdk-components-react test` - `pnpm --filter @webstudio-is/sdk-components-react typecheck` - `pnpm --filter @webstudio-is/sdk-components-react build` - `pnpm --filter @webstudio-is/sdk-components-react dts` - `pnpm --filter @webstudio-is/builder typecheck` - `pnpm --filter @webstudio-is/design-system typecheck` - Targeted Oxlint and Oxfmt checks - `pnpm check:package-boundaries` - `pnpm fixtures` (no fixture diff) Ref #6014 |
||
|
|
e4983b0d1d |
fix: Report unsupported Node versions (#6058)
Closes #6057 ## Outcome Generated projects now reject Node.js versions older than 22.12 before React Router, Remix, or Vite evaluates SDK components. Users see the package-manager engine error with the current and required versions instead of the indirect `sanitize-html` / `htmlparser2` `ERR_REQUIRE_ESM` stack trace. ## Root cause `sanitize-html@2.17.6` synchronously loads the ESM-only `htmlparser2@12`. That dependency combination relies on synchronous `require(ESM)` support, which Node.js enabled by default in 22.12. Generated projects incorrectly declared the broader `>=22` range, allowing an unsupported runtime to reach SSR evaluation. ## Implementation - Set the CLI and all generated base templates to `engines.node: >=22.12.0`. - Add npm `devEngines.runtime` with `onFail: error`, which runs before install, CI, and run commands. - Enable `engine-strict` in generated npm configuration so pnpm also rejects an unsupported runtime. - Regenerate every tracked CLI fixture package manifest. - Update CLI documentation and the release-smoke manifest contract. - Remove the earlier sanitizer-bundling workaround from the branch; sanitizer code and packaging are unchanged from `main`. ## Checklist - [x] Declare the exact Node.js compatibility floor - [x] Fail before generated development, build, and start commands - [x] Cover the generated engine contract with a fail/pass regression - [x] Regenerate and inspect all affected fixtures - [x] Review documentation impact and update the CLI guide - [x] Keep sanitizer behavior and SDK packaging unchanged ## Verification - Regression demonstrated failing before the template metadata change and passing afterward - `pnpm --filter webstudio test` — 946 passed - `pnpm --filter webstudio typecheck` - `pnpm --filter webstudio build` - `pnpm fixtures` - `pnpm lint` - `pnpm exec oxfmt --check` on changed source, template, fixture, and documentation files - `git diff --check` Agent evaluations were not run because they require separate approval. |
||
|
|
1fe087ed26 |
fix: Improve MCP preview and mutation reliability (#6073)
## Summary Fix the second MCP reliability batch across tool discovery, runtime mutations, preview/screenshot setup, Windows process launching, and stdio recovery. ## Implementation - [x] #6071 Accept canonical dotted/kebab tool names and MCP underscore names in `mcp run`; return near matches and `meta.index` guidance for unknown tools. - [x] #6067 Parse JSON-stringified `tools` arrays in `meta.get-more-tools`. - [x] #6069 Preserve resource-backed variables when renaming without a replacement value. - [x] #6068 Parse CSS declaration strings consistently in design-token style updates. - [x] #6065 Fail immediately for occupied explicit screenshot ports and discover Chromium from the Playwright browser cache. - [x] #6066 Recover the stdio MCP transport after an abandoned partial newline-delimited frame. - [x] #6072 Launch managed Windows previews through Node plus `npm-cli.js`, avoiding `spawn EINVAL`. - [x] #6061 Reuse `npm-cli.js` when launched through `npx`, fall back to the Node-adjacent npm CLI on Windows, forward `npm_config_cache`, and include sanitized package-manager diagnostics. - [x] Address review findings: preserve rebinding on resource scope changes and discover default Playwright caches on Linux, macOS, and Windows. - [x] Complete the DRY pass: remove the dead npm command selector, centralize accepted MCP tool-name lookup, simplify stdio frame recovery, and share Levenshtein distance across MCP suggestions and screenshot text matching. - [x] Complete the follow-up review: centralize preview URL port resolution, use `get-port` instead of custom TCP probing, use named resolver dependencies, and correctly reuse owned previews on default HTTP/HTTPS ports. - [x] Complete the final review: use non-reserving `detect-port` checks for explicit ports and repair the generated-app guidance regression coverage. - [x] Audit new utility code against maintained libraries: use `fastest-levenshtein` for edit distance; retain custom stdio recovery, Playwright cache discovery, and npm launching where no supported library API preserves the required behavior. - [x] Audit Windows/macOS/Linux compatibility helpers: use `path-key` for environment PATH casing and `which` for executable discovery; retain explicit Playwright layouts, browser application paths, npm CLI resolution, symlink types, and process-tree shutdown where behavior is platform- or product-specific. - [x] Add fail/pass regression coverage for every fix. - [x] Review documentation impact and update the CLI MCP sources plus generated GitBook output. - [x] Review fixture impact: no fixture inputs or generated fixture bundles are affected. - [x] Run targeted tests, package type checks, lint, package-boundary checks, generated API checks, and generated documentation checks. - [ ] Agent evaluations — not run because repository policy requires separate explicit approval. ## Verification - Complete CLI suite: 60 files, 968 tests passed. - Project-build affected tests: 4 files, 382 tests passed. - `pnpm --filter webstudio typecheck` - `pnpm --filter @webstudio-is/project-build typecheck` - `pnpm lint` - `pnpm check:package-boundaries` - `pnpm check:generated-api` - `pnpm check:generated-docs` Each new regression test was run against the unfixed behavior to confirm the expected failure, then rerun after its fix. ## Compatibility note The stdio recovery layer discards only an unterminated frame that remains idle for five seconds. Complete newline-delimited JSON-RPC frames continue through the SDK transport unchanged. Closes #6072 Closes #6071 Closes #6069 Closes #6065 Closes #6066 Closes #6067 Closes #6068 Closes #6061 |
||
|
|
d5b3f3ab80 |
fix: Improve MCP authoring reliability (#6056)
## Summary This consolidates the reported MCP reliability fixes into one delivery. - validate all inserted fragment expressions with the shared runtime rules and reject text/expression children when component content models require elements - return an actionable error for unsupported existing-resource references in JSX - preserve siblings rendered before expression children - accept unresolved CSS-variable shorthand expansion and eliminate dynamic-alt/`htmlFor` audit false positives - resolve exposed underscore MCP names during focused discovery - omit unavailable stopped-preview fields and restart stale iterative previews for external clients - bound single and responsive screenshot capture, return `SCREENSHOT_TIMEOUT`, and discard failed reusable browser sessions - dispose previews when shared MCP runs fail or stdio clients disconnect, including complete Windows process-tree cleanup - resolve generated route templates from the CLI-managed preview workspace during responsive verification - retry a browser that exits during rendered-audit startup and report sanitized exit diagnostics with a concrete browser-path recovery action - materialize complete current session data before preview generation so route order and project styles cannot collapse from missing lazy namespaces - always include CLI and Node.js version fields in generated issue reports, with explicit legacy-client fallbacks - document the updated preview and screenshot contracts and regenerate the CLI manual The current branch also retains the protections already present on `main` for dry-run isolation, CSS rewrite truncation metadata, stderr-only progress, shortcut argument forwarding, strict MCP schemas, and refreshed conflict diagnostics. ## Technical choices - MCP command orchestration stays in `mcp.ts`; preview port/retry behavior lives with `mcp-preview`, and persisted checkpoint storage lives in `mcp-checkpoint`. Each module owns its matching tests. - Expression validation lives on the shared fragment input schema, reuses `listFragmentExpressions`, and emits the same structured validation issues as prop bindings, so JSX-derived and structured fragments follow one contract across fragment, collection, and runtime UI insertion. - Element-child requirements come from component registry content models during fragment insertion; no component names are hardcoded in the JSX parser. `CollapsibleTrigger` metadata now matches its enforced `asChild` implementation. - Stopped preview status returns only `running: false`; unavailable `url`, `pid`, and `mode` fields are optional and omitted from JSON. - Explicit `preview.start` restarts a stale compatible iterative preview; managed screenshots keep their optimized refresh path. - Screenshot operations share one timeout utility. A single capture or complete responsive batch is bounded after preview readiness; lower-level CDP deadlines use the same stable error code. - Failed managed captures close and forget their browser session. A closed browser session cannot restart itself while cancellation is in progress, which prevents orphaned Chromium processes. - One ownership helper disposes one-shot and multi-project MCP hosts on success or failure. Shared `mcp run` hosts dispose in one `finally` boundary, long-running MCP hosts dispose on connection close, and Windows uses `taskkill /T /F` instead of killing only the npm wrapper. - Framework template readers receive the absolute template directory captured from the build root, so later async work cannot redirect them to the linked project's cwd. The same option drives cleanup for React Router, Remix, and Vike. - Browser startup gets one bounded retry before a rendered capture batch fails. Persistent failures report only the exit code, signal, or spawn error code plus the supported `WEBSTUDIO_BROWSER_PATH` recovery action; local paths and raw browser output are not exposed. - CLI and MCP preview share one session materializer that ensures the canonical Builder namespace set before writing `.webstudio/data.json`. Serialization rejects incomplete snapshots instead of converting missing style/instance namespaces into valid-looking empty arrays, and preview freshness records the post-materialization project version. - The CLI injects its package version and `process.versions.node`; issue formatting now keeps both fields visible even for legacy reports that omit runtime metadata. ## Checklist - [x] Add regression coverage for every changed behavior - [x] Demonstrate new regression tests fail without the corresponding fixes and pass with them - [x] Run affected package test suites and typechecks - [x] Run lint, package-boundary, and generated API checks - [x] Review fixture impact — no fixture inputs or outputs are affected - [x] Review documentation impact and update the authoritative MCP CLI manual source/generated output - [x] Run the complete local agent evaluation suite ## Verification - `@webstudio-is/project-build`: 2,090 tests passed - MCP asset query result modes are preserved across create, read, and update serialization - complete local agent evaluation suite: all 5 fixtures passed, 1,308,276 aggregate tokens - `@webstudio-is/react-sdk`: 140 tests passed - `@webstudio-is/template`: 43 tests passed - `webstudio` CLI: 956 tests passed - issue reporter: 5 targeted tests passed - MCP host disposal regression was demonstrated failing without the shared ownership boundary and passing with it - relevant package typechecks passed - `pnpm lint` passed - `pnpm check:package-boundaries` passed - `pnpm check:generated-api` passed - generated-doc tests, typecheck, sync, and regeneration passed; the aggregate clean-tree command reports the intentionally changed generated CLI manual - stalled single capture, stalled four-viewport capture, startup retry across a four-viewport batch, sanitized browser-exit diagnostics, complete preview materialization, post-refresh version tracking, closed-session restart, Windows process-tree cleanup, and preview-workspace regressions were demonstrated failing without their fixes and passing with them ## Known limitations - External `baseUrl` screenshots remain caller-owned and intentionally do not regenerate, restart, or stop that external server. Closes #6034 Closes #6035 Closes #6038 Closes #6042 Closes #6043 Closes #6044 Closes #6045 Closes #6046 Closes #6047 Closes #6048 Closes #6049 Closes #6050 Closes #6051 Closes #6052 Closes #6059 Closes #6060 |
||
|
|
928867a08b |
fix: Improve MCP CSS variable safety and state feedback (#6018)
Closes #6017 Ref #6019 ## Summary Improve agent-facing CLI/MCP feedback for CSS variables, mutation durability, batch operations, and preview freshness. ## Implementation - Validate structured hex colors as normalized channels and recommend CSS strings for ordinary 0–255 hex input. - Return exact CSS variable values while retaining `valueLength` in compact output for compatibility. - Preserve optional boolean inputs generically in compact MCP SDK schemas, including `withUsage`, `verbose`, `overwrite`, and `force`. - Add multi-variable define/delete examples and document safe batching. - Derive `meta.session.commitStatus` from the session envelope so reads, plans, failed/no-op mutations, and durable mutations are unambiguous. - Retain `committed` on read results for compatibility while reporting `commitStatus: "not-applicable"`. - Report preview `stale` state and `renderedProjectVersion`, and avoid marking a preview fresh when the project changes during regeneration. - Track WSL2/9P cleanup hardening separately in #6019. ## Todo - [x] Reject out-of-range structured hex color channels and alpha. - [x] Add fail-before/pass-after CSS color regression coverage. - [x] Return exact compact CSS variable values without removing `valueLength`. - [x] Clarify mutation durability with `commitStatus`. - [x] Distinguish failed, unchanged, planned, committed, and read-only results. - [x] Distinguish server-backed reads from committed mutations at the session boundary. - [x] Preserve optional boolean schemas without a per-field allowlist. - [x] Add multi-variable define and delete examples. - [x] Report preview freshness and rendered project version. - [x] Investigate WSL cleanup behavior and create follow-up #6019. - [x] Review and update authoritative CLI/MCP documentation. - [x] Verify fixture impact; no fixture inputs or outputs changed. - [x] Run affected tests, typechecks, lint, and generated-file checks. - [ ] Run the complete local agent evaluation suite after explicit approval. ## Verification - [x] Regression tests demonstrated failing before their implementation and passing afterward. - [x] `pnpm --filter @webstudio-is/project-build test` — 82 files, 2,085 tests passed. - [x] `pnpm --filter webstudio test` — 57 files, 939 tests passed. - [x] Project-build and CLI typechecks passed. - [x] `pnpm lint` passed. - [x] `pnpm oxfmt --check` passed. - [x] `pnpm check:generated-api` passed. - [x] `pnpm check:generated-docs` passed. - [ ] `pnpm evaluations` — awaiting explicit approval per repository policy. ## Compatibility and limitations - `committed` remains available on every session result. For reads it is `false` and durability does not apply; use `commitStatus: "not-applicable"`. - Compact CSS-variable records include both exact `value` and `valueLength`. - Structured hex color channels remain normalized `0..1`; CSS color strings such as `"#2d3748"` are the recommended 0–255 representation. - WSL2/9P process cleanup is not changed in this PR and is scoped in #6019. |
||
|
|
8e7a8a21aa |
feat: Report anonymous MCP reliability issues (#6021)
Closes #6020 ## Summary Adds the first end-to-end slice for anonymous, LLM-authored reliability reports from the CLI and MCP. The shared report contract captures the generalized user story, attempted workflow, expectation, actual result, recovery attempts, user impact, technical context, acceptance criteria, and agent runtime (client, provider, model, version, and reasoning effort). Guidance requires removing any user- or project-identifying information before submission. ## Architecture - Adds a project-authenticated `api.reports.issue` tRPC mutation as the reusable product boundary. - Maps that mutation to the public `report-issue` operation for CLI and MCP callers. - Keeps the endpoint directly callable from a future Builder UI through the existing tRPC client. - Publishes through a server-side GitHub App installation, so end users do not need GitHub accounts or tokens. - Discovers the App installation for the fixed Webstudio reporting repository instead of requiring deployment-specific installation or repository configuration. - Searches for a hidden anonymous technical marker before creation to avoid obvious duplicates. ## Todo 1. [x] Define a shared anonymous LLM-authored report contract. 2. [x] Include the user story, attempted workflow, expected and actual behavior, recovery attempts, impact, technical context, and acceptance criteria. 3. [x] Include the LLM client, provider, model, client version when known, and reasoning effort. 4. [x] Attach sanitized CLI, Node.js, operating-system, architecture, execution-mode, and API-contract metadata automatically. 5. [x] Add the Builder-reusable project tRPC mutation. 6. [x] Expose the mutation to CLI and MCP as `report-issue`. 7. [x] Add GitHub App authentication and issue publication. 8. [x] Reduce deployment configuration to the App ID and private key. 9. [x] Add marker-based duplicate detection. 10. [x] Add guidance for explicit user-requested reports and qualifying repeated-friction reports. 11. [x] Review and simplify repeated GitHub request handling and public protocol exports. 12. [ ] Add server-side throttling and harden concurrent duplicate creation. 13. [x] Configure and install the reporting GitHub App in deployed environments. 14. [x] Exercise the deployed endpoint with a controlled test report. 15. [ ] Run the complete agent evaluation suite after explicit approval. 16. [x] Review documentation impact and update the generated MCP documentation. ## Verification - Protocol issue-report contract tests: passed (3) - Builder GitHub reporting tests: passed (4) - Builder API router tests: passed (30) - CLI schema, command-doc, MCP, and project-session tests: passed - Protocol, HTTP client, project-build, CLI, and Builder typechecks: passed - Root lint: passed - Generated API and documentation checks: passed - New and changed regression tests were demonstrated failing against the previous behavior, then passing after implementation - No fixture inputs or outputs are affected - Agent evaluations were not run because they require explicit approval ## Deployment notes The Builder only needs `GITHUB_ISSUE_REPORT_APP_ID` and `GITHUB_ISSUE_REPORT_PRIVATE_KEY`. The server discovers the App installation for `webstudio-is/webstudio` and creates a short-lived installation token. The App needs repository metadata read access and Issues write access. ## Known limitations Duplicate detection currently uses GitHub issue search and can race when identical reports arrive concurrently. The endpoint is project-authenticated, but dedicated server-side throttling remains a follow-up before production rollout. No Builder UI is included yet; the tRPC boundary is intentionally ready for one. |
||
|
|
6385e290c6 |
feat: Add syntax highlighting to Code Text (#6007)
Closes #4119 Supersedes #5999 after GitHub closed it during the head-branch rename. ## Approach Code Text uses one optional public highlighting boundary: - `@webstudio-is/sdk-components-react/code-text` → `src/code-text.tsx` The ordinary `components` entry remains Shiki-free. Canvas loading, metadata options, theme variables, and the plain semantic `<code>` component remain private implementation details. **Code** uses the code editor. **Language** and **Theme** use normal bindable selects. Fixed selections generate direct imports for only the per-page language/theme union; plaintext imports no grammar. Bound selections generate Shiki's lazy language/theme registries. SSR and client rendering share the same factory. Missing bound assets suspend the first render while SSR resolves the selected modules. SSG now waits for Suspense before serializing HTML. During hydration the completed server markup stays in place while the browser fetches only the selected language and theme. Later client-side binding changes load only the new selections and keep the same `<code>` node and focus. Highlighted output preserves the semantic root, ref, author classes/styles, whitespace, escaped source, and legacy children/native `lang` behavior. Shiki's implicit tab stop is disabled. A color-only transformer strips theme typography so asynchronous highlighting cannot change text geometry. ## Bundle impact Measured from same-commit production React Router + Cloudflare builds containing one JavaScript / GitHub Light Code Text instance. Sizes are the sum of emitted JavaScript files; gzip is the sum of each file compressed independently. | Worker output | Files | Raw | Sum gzip | | --- | ---: | ---: | ---: | | Fixed selections | 3 | 1,341,851 B | 288,342 B | | Bound selections | 310 | 10,372,112 B | 1,872,273 B | | Increase | +307 | +9,030,261 B (8.61 MiB) | +1,583,931 B (1.51 MiB) | The bound browser build also emits the catalog as lazy chunks: +9,012,594 raw bytes / +1,578,779 sum-gzip bytes across the complete deployed output. Those chunks are not all delivered on page load. The production SSG regression verifies 100+ catalog chunks are emitted while the HTML directly module-preloads only one shared runtime chunk; the browser fetches the runtime-selected language/theme modules on demand. ## Tradeoffs and compatibility - Instances with both highlighting properties unset keep the legacy plain renderer. - Static highlighting still requires both **Language** and **Theme**. - Binding either selection includes that catalog in deploy output because its runtime value is not known at publish time. - The syntax-highlighting property is `language`; legacy native HTML `lang` remains preserved. - Invalid or unavailable runtime selections render as plain code. - Fixed selections retain the smallest publish output; bound selections trade deploy/worker size for runtime flexibility. ## Todo - [x] Restore the specialized Code Text component and semantic plain fallback - [x] Use a code editor for Code and bindable selects for Language and Theme - [x] Persist JavaScript / GitHub Light template defaults - [x] Collapse highlighting to one public `./code-text` entry - [x] Keep canvas loaders and option/theme helpers private - [x] Generate direct imports for fixed selections and omit plaintext grammar - [x] Generate lazy catalogs when Language or Theme is bound - [x] Preserve highlighted SSR markup during hydration without node/focus movement - [x] Support Suspense-aware highlighted SSG output - [x] Preserve escaping, accessibility, legacy children, and native `lang` - [x] Measure fixed versus bound Cloudflare worker output - [x] Deep-review correctness, DRYness, package surface, and obsolete binding infrastructure - [x] Review documentation impact and update Code Text documentation - [x] Run focused tests, typechecks, production builds, formatting, and staged diff review - [ ] Fixture pipeline — blocked during sync because the current API rejects this local CLI version as incompatible; no fixture output changed ## Verification - [x] New/changed regressions were demonstrated failing without their behavior and passing after restoration - [x] SDK Code Text metadata, rendering, hydration, and bundle tests: 17 passed - [x] Component registry tests: 3 passed - [x] CLI asset collection and full prebuild suite: 59 passed - [x] SDK components, component registry, SDK, and CLI typechecks - [x] SDK components declaration and production builds - [x] Component registry production build - [x] Production Vite + Vike prerender emits highlighted bound SSG HTML with one doctype - [x] Dynamic catalog chunks remain outside the SSG page's direct preload set - [x] Documentation reviewed and updated - [x] Formatting and staged diff checks |
||
|
|
74d88a3fb2 |
fix: Resolve structured Asset paths in queries (#5995)
## Summary Resolve portable relative Asset paths stored in Markdown frontmatter and structured JSON properties to canonical runtime Asset URLs inside the content engine. The authored source remains unchanged. Asset resource consumers now receive canonical URLs without Image, CSS, JSON-LD, or other binding-specific transformations. ## Root cause Markdown body links already recorded relative Asset references for runtime rewriting, but structured values bypassed that pipeline. Browsers therefore resolved values such as `./assets/hero.png` against the page URL instead of the source document folder. ## Implementation - Recursively discover unique structured Asset references using the existing canonical path resolver and the platform URL parser. - Store optional `assetValueReferences` in content artifacts and runtime projections. - Include referenced Assets in publication/runtime dependency collection and validation. - Resolve values before filtering, sorting, and projection in normal and document-graph queries. - Rewrite materialized query items at runtime without mutating canonical documents or compiled rows. - Merge authored query parameters and fragments with canonical Asset URLs. - Keep queries whose filter/sort semantics depend on runtime Asset URLs out of compile-time materialization. - Add an explicit content-compilation cache generation so pre-feature artifacts are recompiled. - Refresh fixture bundle versions and the generated asset-query runtime. - Document relative references in Markdown frontmatter and JSON content. ## Checklist - [x] Add structured reference discovery for nested objects and arrays - [x] Support Markdown frontmatter and JSON document properties - [x] Preserve URL query strings and fragments - [x] Thread references through build/runtime artifacts and publication dependencies - [x] Resolve normal, materialized, and document-graph query results - [x] Apply resolved values to filtering, sorting, and projection - [x] Preserve compatibility with artifacts that omit the optional field - [x] Add fail/pass regression coverage - [x] Run package tests, typechecks, lint, and generated API checks - [x] Regenerate and build all fixtures - [x] Review documentation impact and update the Assets guide ## Verification - `pnpm --filter @webstudio-is/content-engine test` — 269 passed - `pnpm --filter @webstudio-is/content-engine typecheck` — passed - `pnpm --filter @webstudio-is/asset-uploader test` — 184 passed - `pnpm --filter @webstudio-is/asset-uploader typecheck` — passed - `pnpm --filter @webstudio-is/protocol test` — 88 passed - `pnpm lint` — passed - `pnpm check:generated-api` — passed; generated files clean - `pnpm --filter webstudio build:content-runtime && pnpm -r fixtures:build` — passed for all fixtures - Assets documentation — internal links resolve and `git diff --check` passes - Regression proof: neutralizing structured discovery/replacement caused 8 expected failures across source compilation, standard queries, document-graph queries, and materialized queries; restoring the implementation passed all tests. - `pnpm evaluations` — not run because explicit approval is required. ## Compatibility The artifact field is optional, so older artifacts continue to parse and execute. Existing absolute, protocol-relative, root-relative, fragment-only, query-only, external-scheme, malformed, missing, and ambiguous values remain unchanged. |
||
|
|
1f4095cf9a |
fix: Improve generated MCP documentation (#5991)
## Summary
- render the generated MCP version as visible body content immediately
below the page heading
- keep the GitBook navigation label stable as `MCP`
- stamp only the CLI version placeholder during release publication,
leaving Markdown content owned by the template
- remove empty `{}` blocks from the rendered MCP argument examples while
preserving meaningful examples and complete structured JSON data
## Root cause
GitBook uses the `SUMMARY.md` link label as the published page heading
and suppresses the Markdown H1 from the document body. The generated
version was therefore present in source but absent from the rendered
page.
The release workflow also coupled version stamping to the complete
rendered Markdown line. It now replaces and verifies only the standard
`0.0.0-webstudio-version` placeholder.
## Verification
- live page structure inspected: published H1 is `MCP`
- MCP manual regression test demonstrated failing before empty argument
blocks were filtered, then passing after the fix
- release placeholder stamping simulated against the generated page
- `pnpm --filter webstudio exec vitest run src/commands/man.test.ts`
- `pnpm --filter @webstudio-is/project-build typecheck`
- `pnpm --filter webstudio typecheck`
- `pnpm check:generated-docs`
- `pnpm lint`
- `pnpm oxfmt --check packages/project-build/src/mcp.ts
packages/cli/src/commands/man.ts packages/cli/src/commands/man.test.ts`
- `git diff --check`
Fixture inputs and outputs are unaffected.
## Todo
- [x] Generate the release version as visible GitBook body content.
- [x] Decouple release stamping from the rendered Markdown content.
- [x] Remove empty MCP argument example blocks.
- [x] Validate generated output and regression coverage.
- [ ] Merge this pull request.
- [ ] Publish the latest released revision to the `docs` branch.
- [ ] Verify the version on the live GitBook page.
Ref #5986
|
||
|
|
e6a29b5d36 |
fix: Show released CLI version in MCP docs (#5990)
## Summary - make the MCP page generator render the CLI package version directly in the page title - publish `Webstudio MCP v<release>` from the exact generated page in each successful release - merge each successful release tag into the publication-only `docs` branch - serialize publication and ignore reruns or older release tags already contained in `docs` ## Root cause The first publication design advanced `docs` to the release commit without putting the CLI package version into the generated page. The repository uses `0.0.0-webstudio-version` until release time, so the release workflow now replaces that existing version placeholder with the successful tag version before publishing. ## Todo - [x] Generate the CLI version in the MCP page title. - [x] Publish the generated page from the exact release revision. - [x] Make publication idempotent and prevent version downgrades. - [x] Validate generation, formatting, linting, and release-branch behavior. - [ ] Merge this pull request. - [ ] Publish `0.285.0` as the initial version on the existing `docs` branch. ## Verification - `pnpm docs:mcp:test` - `pnpm docs:mcp:typecheck` - `pnpm check:generated-docs` - `pnpm lint` - `pnpm oxfmt --check` - `git diff --check` - isolated Git simulation for release merge, exact generated-page selection, version replacement, and rerun detection - regression tests demonstrated failing without version rendering and validation, then passing after restoration Ref #5986 |
||
|
|
99371187dc |
docs: Move product documentation into Builder (#5987)
## Summary - move the complete GitBook documentation tree and assets into Builder under `/docs` - generate the exhaustive MCP page from the local CLI source in the same change - publish GitBook from a release-gated `docs` branch containing the exact successfully released revision - run MCP documentation tests, typechecking, and stale-output checks with the existing generated-docs check - remove links to the Community Discussions repository ## Technical choices - Import the current documentation as a linear snapshot so the branch satisfies Builder's required-linear-history protection. - Keep the Markdown wrapper separate from the TypeScript generator at `scripts/docs/mcp-page.md`. - Generate through `packages/cli/local.js` so CLI guidance and its documentation are reviewed together. - Let `check:generated-docs` reject CLI changes that leave the committed MCP page stale. - After both GitHub release creation and package publication succeed, fast-forward the read-only `docs` branch to the immutable release tag commit. A divergent update fails instead of publishing a different revision. - Configure GitBook to publish `/docs` from the `docs` branch, not directly from `main`. - Exclude `/docs` from the repository-wide `oxfmt` scan so imported GitBook Markdown retains its established formatting; generator tests and stale-output checks still validate the MCP page. - Exclude `transcripts/` and GitHub Discussions from the migration. ## Todo - [x] Import documentation, navigation, includes, and assets under `/docs`. - [x] Generate the MCP page from the local CLI source. - [x] Move MCP generation and validation into Builder. - [x] Require MCP documentation updates alongside CLI changes. - [x] Publish released revisions through a read-only `docs` branch. - [x] Remove Community repository links from Builder and the migrated docs. - [x] Preserve and verify a final Community Git bundle locally. - [ ] Merge this pull request. - [ ] Let the next successful release create or advance the `docs` branch. - [ ] Repoint GitBook Git Sync to `webstudio-is/webstudio`, branch `docs`, root directory `/docs`. - [ ] Verify `docs.webstudio.is`, navigation, assets, anchors, and the MCP page in production. - [ ] Delete `webstudio-is/webstudio-community`. ## Verification - `pnpm check:generated-docs` - `pnpm lint` - `pnpm oxfmt --check` - `git diff --check origin/main...HEAD` - generator regression test demonstrated failing when the GitBook wrapper behavior was removed, then passing after restoration - no fixture inputs or outputs are affected ## Known limitation All documentation merged after the previous release waits for the next successful release before GitBook publishes it. This deliberately keeps the public MCP reference aligned with an installable CLI revision. Ref #5986 |
||
|
|
310166343b | first working version of designer in turborepo | ||
|
|
c19406ff56 | better testing cases | ||
|
|
5b6ee08a14 | add test cases | ||
|
|
9510684475 | breakpoints test cases | ||
|
|
0123c7598d | Create test-cases.md |