diff --git a/apps/solidcraft-web/index.html b/apps/solidcraft-web/index.html index 57c307a56..d9d535b49 100644 --- a/apps/solidcraft-web/index.html +++ b/apps/solidcraft-web/index.html @@ -9,7 +9,7 @@ - + diff --git a/docs/book/src/guide/getting-started.md b/docs/book/src/guide/getting-started.md index a3c8d9e3b..e0461dcf8 100644 --- a/docs/book/src/guide/getting-started.md +++ b/docs/book/src/guide/getting-started.md @@ -136,10 +136,6 @@ keeps its designs, settings and recovery copies apart from the release's, so try changes what the release sees, and nothing is copied between them: to move a design, save it to a file in one and open the file in the other. Search engines are told to skip both. -Planned worker and tiered-storage integration is -described in [web-runtime.md](https://github.com/tangency-labs/solidcraft/blob/main/docs/web-runtime.md) -(design; not yet wired in the shipped wasm build). - After the first visit the web app works offline: the browser keeps a copy of it. Online, each launch gets the latest published build (the browser downloads it once when it changes); offline, when the network doesn't answer within a few seconds, or when a new build can't be downloaded diff --git a/docs/mcp.md b/docs/mcp.md index 68fe54d19..cb8b31ac7 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -10,8 +10,7 @@ ordinary `execute` tool: `render.preflight`, `render.start`, `render.status`, `render.cancel` and `render.export`. Keep the complete returned job ID; image bytes remain in the session until explicit PNG export. See [render jobs](render-jobs.md). -For how the same command surface should work in the browser (workers, tiered storage, in-tab -agents), see [web-runtime.md](web-runtime.md). For sandboxed plugins and parametric timeline +For sandboxed plugins and parametric timeline features that also use `run(command, args)`, see [plugins.md](plugins.md). Desktop MCP in this document remains the reference implementation today. diff --git a/docs/plugins.md b/docs/plugins.md index aa5bb724c..06981ff69 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -2,8 +2,7 @@ Design companion to [#1221](https://github.com/bherbruck/solidcraft/issues/1221): sandboxed WebAssembly plugins with a WIT interface, the same `run(command, args)` JSON as -[MCP](mcp.md) and the [control protocol](control-protocol.md). Browser hosting is in -[web-runtime.md](web-runtime.md). +[MCP](mcp.md) and the [control protocol](control-protocol.md). This document adds **parametric timeline features**: a generic host-owned feature shell that plugins fill with parameters, display metadata, and rebuild logic, without a second timeline @@ -100,7 +99,7 @@ Manifest declares **`fallback_policy`**: | `suppress_with_warning` | Feature suppressed; user sees clear message | | `error_on_rebuild` | Hard fail on eval (strict teams) | -Design files shared in CollabCraft should prefer a policy that **opens safely** (`recorded_mesh` or +Shared design files should prefer a policy that **opens safely** (`recorded_mesh` or `recorded_script`). CI for plugins (#1221) should include: uninstall plugin, reopen file, assert document still opens and policy matches manifest. @@ -123,12 +122,9 @@ header carries `PluginDisplay` metadata while children are ordinary native featu not need the plugin until the user edits plugin-owned params on the header. Migrates cleanly to full `FeatureKind::Plugin` when `evaluate` lands. -## Relationship to craft-libs +## Where the code lives -Plugin **document model and eval** stay in SolidCraft (`crates/doc`, `crates/engine`). craft-libs -provides worker/broker hosting only ([web-runtime.md](web-runtime.md)). Neutral serde types -(`VersionedParams`, `PluginDisplay`) may move to a shared crate later if multiple apps need them; -CAD plugins remain SolidCraft-specific. +Plugin **document model and eval** stay in SolidCraft (`crates/doc`, `crates/engine`). ## Phasing diff --git a/docs/web-runtime.md b/docs/web-runtime.md deleted file mode 100644 index 8f65c4659..000000000 --- a/docs/web-runtime.md +++ /dev/null @@ -1,156 +0,0 @@ -# Browser runtime (design) - -Design note for SolidCraft in the browser: tiered storage, worker offload, GPU jobs, and -agent control that stay aligned with the desktop app, the control channel, and -[MCP](mcp.md). Implementation lives primarily in -[craft-libs](https://github.com/storytold/craft-libs) (`craft-tier-store`, `craft-worker-host`, -`craft-gpu`, `craft-runtime`); SolidCraft wires those crates into -[`apps/solidcraft-web`](../apps/solidcraft-web) and [`files.rs`](../apps/solidcraft-web/src/files.rs) -rather than growing a second stack here. - -Related: [plugins.md](plugins.md) and [#1221](https://github.com/bherbruck/solidcraft/issues/1221) -(desktop WIT + wasmtime first; parametric timeline features in phase 2), [design containers](design-container.md), -[control protocol](control-protocol.md). - -## Problem - -The wasm app today ([`getting-started`](../docs/book/src/guide/getting-started.md)) keeps designs in -the origin private file system (OPFS) behind virtual `/opfs/` paths, with optional File System -Access import/export. That works for small and medium designs but hits three walls: - -| Wall | Symptom in SolidCraft | -|------|------------------------| -| Quota | Large STEP imports and container blobs compete with autosave and cache in OPFS | -| Main thread | Open, save, and timeline evaluation run synchronously on the UI thread with egui | -| Agents | MCP runs out of process (`solidcraft-cli mcp`); the tab has no first-class agent session | - -WebGPU for the viewport already runs on the main thread (wgpu via eframe). Moving the entire UI -renderer into a worker is out of scope for the first integration; worker GPU is for offload jobs -(tessellation warm paths, future kernel work), not for egui. - -## Principles - -1. **One command surface.** Toolbar, scripts, control channel, MCP, and (eventually) in-browser - agents all use the same engine commands. Dialog-free commands only for unattended paths, same - rule as [MCP](mcp.md). -2. **Generic traits in craft-libs.** Storage tiers, worker RPC, and GPU dispatch are implemented - once in craft-libs. Web and native use the same traits; hosts differ (OPFS vs paths, SharedWorker - vs thread pool). -3. **Do not duplicate cloud IO.** Authenticated cloud Open/Save uses `craft-cloud` and CollabCraft - ([craft-libs #48](https://github.com/storytold/craft-libs/pull/48)). Browser-local tiers - (`craft-tier-store`) are separate: hot mirror, warm cache, cold working folder, optional range - reads of cloud blobs through CollabCraft without vendor types in generic crates. -4. **One worker broker.** A SharedWorker (or dedicated-worker fallback) coordinates storage writes, - job queues, and shared wasm module compile per origin. Plugins and offload jobs register on the - broker; do not spawn one SharedWorker per plugin ([#1221 comment thread](https://github.com/bherbruck/solidcraft/issues/1221)). - -## Architecture - -```text -Main thread (tab) - eframe + viewport WebGPU - hot mirror (sync reads for engine) - craft_runtime HostFacade ----MessagePort RPC----> SharedWorker broker - tier-store coordinator (single writer) - job queue + dedup - headless engine session(s) - optional dedicated GPU workers - ProviderRegistry (GpuJob dispatch) - -Tiers (craft-tier-store) - Hot RAM mirror, LRU budget - Warm OPFS under craft//… (today: /opfs/ mapping) - Cold File System Access project folder (no duplicate bytes in OPFS) - Cloud craft-cloud refs, range fetch via CollabCraft API (not in wasm credentials) -``` - -On **desktop**, the same `BlobStore` and job envelopes apply: warm/cold map to normal directories; -[`solidcraft-cli mcp`](mcp.md) and wasmtime plugin hosts ([#1221](https://github.com/bherbruck/solidcraft/issues/1221)) -call the same `run(command, args)` JSON. - -## Mapping SolidCraft today - -| Today | Target | -|-------|--------| -| [`files.rs`](../apps/solidcraft-web/src/files.rs) OPFS + `/opfs/` VFS | Warm tier keys; migration keeps existing filenames initially | -| Recovery autosave | Warm tier, same semantics as [`compatibility.md`](compatibility.md) | -| [Design containers](design-container.md) content-addressed blobs | Tier keys by hash; cold tier holds large blobs without copying into OPFS | -| [Control protocol](control-protocol.md) over TCP | Same methods over `MessagePort` to broker headless session (WebMCP-shaped, not a second registry) | -| Parallel mesh work ([roadmap detail](roadmap-detail.md): web path serial) | Offload eval / IO jobs via `JobSubmit`; viewport stays on main thread | - -## craft-libs crates (reference) - -These names follow the craft-libs performance platform design; SolidCraft depends on them as -published from storytold/craft-libs after cloud contracts land (#48, #52). - -| Crate | Role | -|-------|------| -| `craft-tier-store` | `BlobStore`, tier policy, sync mirror over async persist; native + wasm hosts | -| `craft-worker-host` | SharedWorker bootstrap, RPC messages (`Init`, `StorageOp`, `JobSubmit`, …) | -| `craft-gpu` | `GpuContext`, `GpuJob`, `GpuProvider`, `ProviderRegistry` (no app WGSL here) | -| `craft-gpu-wgpu` | wgpu backend: WebGPU on wasm32, Vulkan/DX12/Metal on desktop | -| `craft-gpu-providers` | Shared readback/composite helpers extracted from Craft app gpu crates | -| `craft-runtime` | Facade: tier store + worker host + optional `cloud-delegate` hooks | - -Generic runtime code must not depend on SolidCraft crates. SolidCraft registers app-specific -providers and key namespaces only. - -## GPU and the viewport - -- **Main thread:** eframe owns the WebGPU device used for the 3D view and UI. -- **Workers:** `craft_runtime::gpu::dispatch(registry, jobs)` runs `GpuJob` lists (chunked buffers, - readback fences) for offload; same entry point on native thread pools. -- **Limits:** Capability probe once at init; UI and workers share reported max buffer sizes. - -## Agents in the browser - -| Mode | Transport | -|------|-----------| -| Desktop agent | `solidcraft-cli mcp` (stdio) or `--connect` to [control protocol](control-protocol.md) | -| Browser agent | RPC to broker session; dialog-free tools only | -| IDE bridge | Optional local relay (stdio MCP ↔ tab); not required for CollabCraft-hosted wasm | - -File policy for web agents mirrors MCP folders: design directory, cold tier roots, recovery; -never `--allow-any-path` in the tab. - -## Plugins ([#1221](https://github.com/bherbruck/solidcraft/issues/1221)) - -| Host | Runtime | -|------|---------| -| Desktop | wasmtime + fuel/memory limits; WIT `solidcraft:plugin@1.0.0` with `run`, `manifest`, permissions | -| Web | Component or module in broker; same WIT contract; sandbox = manifest permissions enforced before `run()` | - -Milestone 1: one-shot commands and importers/exporters. Milestone 2: **parametric timeline -features** via a generic host-owned `FeatureKind::Plugin` shell (params + display metadata -including timeline icon and label); plugins rebuild through WIT `evaluate()` calling the same -`run()` JSON. See [plugins.md](plugins.md). Command ids may use a `pluginname.function` prefix to -avoid collisions. - -## CollabCraft deployment - -Static wasm apps on `craft.quasarke.net` ship `craft-worker-host.js` (brotli-precompressed) beside -the app bundle. Prefer one global runtime worker per origin once message routing and wasm size are -budgeted; per-app worker URLs are acceptable for pilots. CSP must allow `worker-src` / SharedWorker. - -## Phasing (SolidCraft) - -1. **Document and track** (this file); no user-visible change. -2. **Tier-store wiring:** replace ad-hoc OPFS glue with `craft-tier-store` keys; keep on-disk layout. -3. **Worker broker:** headless `engine.execute` batches and container IO off UI thread. -4. **Agent bridge:** MessagePort tool surface equivalent to MCP dialog-free tools. -5. **Plugins on web:** after desktop wasmtime milestone and WIT stability. -6. **Parametric plugin features:** [plugins.md](plugins.md) phase 2 (`evaluate`, display metadata, fallback policy). - -## Out of scope (initial integration) - -- Moving egui/viewport WebGPU into SharedWorker -- Second non-wgpu GPU backend in craft-libs -- **Implementing** parametric `FeatureKind::Plugin` (designed in [plugins.md](plugins.md); follows craft-runtime wiring) -- Duplicating `craft-cloud` or embedding `craft-nextcloud` in SolidCraft wasm - -## Tests - -- Extend control-channel scenarios for broker RPC parity where methods map 1:1 -- Worker tests: SharedWorker multi-tab dedup (EffectCraft `workers.mjs` pattern) -- Tier-store: native LRU tests + wasm OPFS smoke -- GPU: golden frames remain in app crates; craft-gpu-null for CI dispatch smoke diff --git a/skills/solidcraft-performance/SKILL.md b/skills/solidcraft-performance/SKILL.md index 742208da7..64aafa8ac 100644 --- a/skills/solidcraft-performance/SKILL.md +++ b/skills/solidcraft-performance/SKILL.md @@ -22,4 +22,4 @@ description: "Use when a SolidCraft change is slow, blocks the window, runs long - Everything below the apps must build for `wasm32-unknown-unknown`: `cargo xtask wasm` checks every library crate and the web app, and is part of `cargo xtask ci`. Do not add a dependency that cannot. - Application code is Rust only. The browser requires two pieces of JavaScript: the service worker `apps/solidcraft-web/sw.js` and the small inline scripts in `apps/solidcraft-web/index.html`. Keep them minimal; `cargo xtask web-offline-test` covers the service worker. - Python 3.11+ is allowed only for asset authoring, lint and review tools (`assets/AGENTS.md`), never as an application dependency. -- Design notes for the browser runtime: `docs/web-runtime.md`, `docs/browser-api.md`. +- Design notes for the browser runtime: `docs/browser-api.md`.