Skip to content

feat: add queryable Assets resources#5921

Open
kof wants to merge 10 commits into
mainfrom
agent/5919-asset-resource
Open

feat: add queryable Assets resources#5921
kof wants to merge 10 commits into
mainfrom
agent/5919-asset-resource

Conversation

@kof

@kof kof commented Jul 18, 2026

Copy link
Copy Markdown
Member

Summary

This PR extends the existing Assets system resource with optional GROQ queries while preserving its fetch-all behavior by default. It adds canonical asset metadata, query-owned immutable indexes, Builder query tooling and autocomplete, selected-file content hydration, generated-app runtime support, and MCP parity.

Implementation decisions

Resource and query contract

  • Keep one user-visible Assets resource.
  • Preserve the existing GET request and response when no query is configured.
  • Switch the same resource to the internal POST /$resources/assets/query transport only when query configuration is enabled.
  • Use GROQ rather than a Webstudio-specific query language.
  • Support runtime parameters, deterministic result limits, projections, ordering, and explicit content hydration.
  • Treat frontmatter fields, including draft, as schema-less user data rather than built-in system policy.

Canonical metadata and indexes

  • Parse Markdown YAML frontmatter through the existing unified/remark stack.
  • Store dynamic fields under properties, separate from stable asset metadata.
  • Maintain canonical per-file metadata so changing a query does not reopen every Markdown file.
  • Build one immutable, query-specific index from canonical metadata.
  • Identify an index by resource, query hash, and canonical asset revision.
  • Use versioned deterministic JSON with content references instead of complete file bodies.
  • Keep object storage private behind authenticated services; the Builder never accesses R2 directly.
  • Activate revisions atomically and retain revisions referenced by resources, builds, previews, or deployments.
  • Garbage-collect obsolete unreferenced revisions.

Builder and MCP

  • Add optional query controls to the existing Assets resource editor.
  • Use CodeMirror 6 and the GROQ Lezer grammar for editing.
  • Build autocomplete from GROQ syntax, runtime parameters, stable asset fields, and the persisted dynamic field catalog.
  • Load field catalogs and previews lazily through authenticated APIs.
  • Expose semantic MCP operations for listing, creating, updating, validating, previewing, inspecting, and rebuilding Assets queries.

Publication and runtime

  • Snapshot the exact immutable index revision used by each build.
  • Materialize Markdown and index JSON through the normal deployment asset pipeline.
  • Access deployed files through the Cloudflare Assets binding or the equivalent generated-app asset boundary, never direct R2 access.
  • Hydrate full or partial text only after GROQ has selected asset identities.
  • Support dynamic SSR detail routes and optional SSG prerendering.
  • Include the published GROQ integration only when a project contains query-enabled Assets resources.
  • Keep MDX compilation and Webstudio-fragment authoring separate in Support MDX-authored pages with portable Webstudio fragments #5920.

Implementation checklist

1. Contracts and compatibility

  • Define the canonical asset document, query request/response, limits, hydration options, and structured errors.
  • Preserve the legacy Assets fetch-all request and response.
  • Unify query configuration with the existing Assets resource.
  • Add runtime parameter serialization and Builder/generated transport parity tests.
  • Document that draft is conventional frontmatter rather than built-in publication behavior.

2. Canonical asset metadata

  • Add bounded Markdown frontmatter, body, and excerpt extraction.
  • Persist deterministic per-file canonical metadata and dynamic field contributions.
  • Add initial synchronization, changed-file detection, recovery, and deletion handling.
  • Update filename and folder-derived metadata after asset moves.
  • Reparse canonical content when a patch swaps an asset's storage revision through asset.name.
  • Make standard-metadata updates race-safe against concurrent content revisions.
  • Add integrated regression coverage for add, delete, move, rename, revision swap, and concurrent synchronization.

3. Query indexes and lifecycle

  • Add the versioned deterministic JSON index format and integrity validation.
  • Build static and parameterized candidate sets from canonical metadata.
  • Persist immutable revisions and atomically activate matching query/asset revisions.
  • Track build, resource, and deployment references.
  • Delete obsolete unreferenced index objects.
  • Reconcile and validate indexes before publication.
  • Give each build attempt a unique identity so one concurrent identical attempt cannot fail or cancel another.
  • Bind precomputed asset revisions to their prepared canonical entry set instead of accepting an unrelated digest.
  • Skip index work for asset changes that do not affect canonical query data.
  • Run garbage collection once per mutation/publication batch instead of once per resource build.

4. Builder query experience

  • Add query, parameter, result-limit, hydration, preview, and status controls to the Assets resource.
  • Add CodeMirror GROQ highlighting and syntax-aware completion.
  • Build and expose a dynamic field catalog with nested paths and observed types.
  • Show indexing, stale, invalid, failed, and empty states.
  • Avoid downloading all Markdown files during Builder startup or editor opening.
  • Consolidate the duplicated GROQ AST traversal used by validation, candidate selection, and field discovery.
  • Share one parameter-name validator across SDK schemas, Builder validation, completion, and project-build.

5. Published applications

  • Snapshot required index revisions into the project bundle.
  • Materialize index JSON and Markdown through deployment assets.
  • Evaluate runtime GROQ and hydrate selected content through the asset binding.
  • Cache immutable parsed indexes and properly keyed query results.
  • Support dynamic SSR detail pages without per-post prerendering.
  • Support SSG prerendering when requested.
  • Avoid adding the GROQ runtime to generated applications that do not use queried Assets resources.

6. MCP parity and real-world validation

  • Add semantic MCP operations for Assets query configuration, preview, fields, status, and rebuild.
  • Create five Markdown articles through MCP.
  • Build and validate an overview page and a dynamic slug detail page.
  • Verify the listing hydrates zero bodies and the detail resource hydrates exactly one body.
  • Verify enabling and disabling query mode on the same Assets resource.
  • Ensure query changes reliably persist index state, then retest the structured index-status operation.
  • Return an actionable structured error for MCP screenshot failures and complete visual verification.
  • Add a main landmark to the overview test page and rerun its accessibility audit.

7. Test quality and final hardening

  • Add parser, query, index, hydration, storage, lifecycle, publication, and scale tests.
  • Add a 1,000-file scale fixture and benchmark scripts.
  • Add Builder/generated transport and blog-flow coverage.
  • Replace new module-level mocks with dependency injection or protocol-level fakes where integration behavior matters.
  • Run final targeted suites, typechecks, formatting, package-boundary checks, and generated-app validation after the remaining fixes.
  • Perform a final correctness, concurrency, DRY, and backward-compatibility review.

Validation completed

  • Asset resource, asset uploader, SDK, Builder-focused, CLI prebuild, and project-build suites
  • Relevant package typechecks, formatting, lint, package-boundary, and diff checks
  • Architecture validation that Markdown and index JSON remain outside Worker JavaScript
  • Real-world MCP blog flow with five Markdown posts, overview, and dynamic detail page
  • Scale fixtures and benchmarks for 1,000 schema-less Markdown files
  • Unique-attempt concurrency, exact canonical-revision binding, revision-swap, irrelevant-change, and batch-cleanup regressions
  • Connected MCP screenshot failure regression with actionable structured recovery guidance
  • Stored five-article overview fixture accessibility audit after adding its main landmark (zero findings)

All implementation and validation checklist items are complete.

Closes #5919
Ref #5920

kof added a commit that referenced this pull request Jul 20, 2026
## 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend Assets resources with optional GROQ queries

1 participant