Built-in design generation now runs as an agentic MCP tool-loop (reusing the agent-rs BuiltInProvider), gated behind OPENPENCIL_DESIGN_AGENT_LOOP / the Settings experimental toggle; the orchestrator stays the default. - design-agent system prompt + in-process design toolset (parity-locked with the MCP surface) + flag-gated Intent::Design routing - spawn_agents execution as sequential sub-loops + live creation-mode badges (per-agent glow + 'N/M designing...' header) - new MCP tools: get_guidelines, ToolSearch, get_screenshot, get_editor_state, export_nodes, spawn_agents; style-guide local audit - #27 AI panel restyle: rounded tool cards + green check-rings, gray user bubbles, model-pill bottom toolbar, header, empty-state pills, the PARALLEL AGENTS (agent_team_size) 1x-6x chip dropdown - multi-chat tabs: ChatSessions model (Deref-to-active) + tab row UI (switch / close / + / Cmd+T) with each run bound to its tab Large checkpoint commit spanning the working tree (Rust shell crates).
97 lines
4.3 KiB
Bash
Executable file
97 lines
4.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# tools/check-wasm-bundle.sh — Step 1b §6 + §7.1 local bundle gate.
|
|
#
|
|
# What this script enforces (matches the CanvasKit production bundle gate
|
|
# and the env.* import count guard):
|
|
# 1. Required local tools are available: cargo, wasm-bindgen, wasm-opt,
|
|
# node, and gzip. CanvasKit needs no EMSDK / skia-safe / libc shim.
|
|
# 2. cargo build → wasm-bindgen → wasm-opt -Oz pipeline produces the
|
|
# served crates/op-host-web/pkg/op_host_web_bg.wasm. `wasm-opt` is invoked
|
|
# with the core WebAssembly features emitted by current rustc.
|
|
# 3. Post-bindgen bundle has 0 env.* imports
|
|
# (i.e. all imports come from `./op_host_web_bg.js`,
|
|
# the wasm-bindgen JS shim). Any env.* import = LinkError at
|
|
# load time → regression → fail.
|
|
# 4. Post wasm-opt -Oz gzip size ≤ STEP1B_SHELL_WASM_GZIP_LIMIT_BYTES
|
|
# (default 6 291 456 bytes = 6 MiB for the full CanvasKit app logic).
|
|
#
|
|
# This script is the local counterpart to
|
|
# `.github/workflows/wasm-bundle-build.yml`; keep the two recipes aligned.
|
|
#
|
|
# Exit semantics:
|
|
# 0 all four checks PASS.
|
|
# 1 any check FAILED — message names which one.
|
|
# 2 prerequisite missing (cargo / wasm-bindgen / wasm-opt / node / gzip).
|
|
|
|
set -euo pipefail
|
|
|
|
CRATE_DIR="crates/op-host-web"
|
|
PKG_DIR="${CRATE_DIR}/pkg"
|
|
WASM_RAW="${PKG_DIR}/op_host_web_bg.wasm"
|
|
WASM_OPT="${PKG_DIR}/op_host_web_bg.opt.wasm"
|
|
TARGET_WASM="target/wasm32-unknown-unknown/release/op_host_web.wasm"
|
|
WASM_OPT_FEATURES=(
|
|
--enable-bulk-memory
|
|
--enable-bulk-memory-opt
|
|
--enable-nontrapping-float-to-int
|
|
)
|
|
|
|
# Ceiling for the CanvasKit production bundle's gzipped wasm. It is far above
|
|
# the retired skia raster path's 1 MiB (spec §6) because this bundle now carries
|
|
# the FULL app logic absorbed from the skia path (codegen AI pipeline, Figma
|
|
# parser, AI/live-sync). ~4.5 MiB today. TODO(perf): code-split / lazy-load the
|
|
# codegen + Figma paths to shrink the initial download. Override via env.
|
|
LIMIT="${STEP1B_SHELL_WASM_GZIP_LIMIT_BYTES:-6291456}"
|
|
|
|
step() { printf '\n[step %d/%d] %s\n' "$1" "$2" "$3"; }
|
|
fail() { printf 'FAIL: %s\n' "$1" >&2; exit 1; }
|
|
need() { command -v "$1" >/dev/null 2>&1 || { printf 'missing prerequisite: %s\n' "$1" >&2; exit 2; }; }
|
|
|
|
step 1 5 "Verify prerequisites"
|
|
need cargo
|
|
need wasm-bindgen
|
|
need wasm-opt
|
|
need node
|
|
need gzip
|
|
# CanvasKit needs NO EMSDK / skia-safe / libc shim — the editor renders through
|
|
# the official CanvasKit skia WASM (loaded separately from /canvaskit/) and the
|
|
# Rust bundle is pure logic. (The retired skia raster path needed EMSDK.)
|
|
|
|
# `canvaskit` is the production browser feature set: the editor renders through
|
|
# CanvasKit on the GPU and bundles the full app logic absorbed from the retired
|
|
# skia raster path — daemon-backed AI chat (`web_chat`), live-sync, browser file
|
|
# IO, clipboard/Figma paste, icon search, system fonts, and the codegen pipeline.
|
|
step 2 5 "Build shell-web wasm32-unknown-unknown with --features canvaskit"
|
|
cargo build -p op-host-web \
|
|
--target wasm32-unknown-unknown --no-default-features --features canvaskit --release >/dev/null
|
|
|
|
step 3 5 "wasm-bindgen --target web → ${PKG_DIR}/"
|
|
wasm-bindgen --target web --out-dir "${PKG_DIR}" "${TARGET_WASM}" >/dev/null
|
|
|
|
step 4 5 "Verify 0 env.* imports (spec §7.1 import guard)"
|
|
env_count="$(node -e '
|
|
const fs = require("fs");
|
|
const buf = fs.readFileSync(process.argv[1]);
|
|
WebAssembly.compile(buf).then(mod => {
|
|
const imps = WebAssembly.Module.imports(mod);
|
|
const env = imps.filter(i => i.module === "env");
|
|
console.log(env.length);
|
|
}).catch(e => { console.error("compile failed:", e); process.exit(1); });
|
|
' "${WASM_RAW}")"
|
|
if [ "${env_count}" != "0" ]; then
|
|
fail "env.* import count = ${env_count} (must be 0); the CanvasKit bundle has no libc shim, so an env.* import means a dep pulled non-wasm-clean code — find and gate it out"
|
|
fi
|
|
printf ' ✓ 0 env.* imports\n'
|
|
|
|
step 5 5 "Verify gzip size ≤ ${LIMIT} bytes (spec §6 ceiling)"
|
|
wasm-opt "${WASM_OPT_FEATURES[@]}" -Oz "${WASM_RAW}" -o "${WASM_OPT}" >/dev/null
|
|
cp "${WASM_OPT}" "${WASM_RAW}"
|
|
gz_bytes="$(gzip -c "${WASM_OPT}" | wc -c | tr -d ' ')"
|
|
if [ "${gz_bytes}" -gt "${LIMIT}" ]; then
|
|
fail "shell-web wasm gzip size ${gz_bytes} bytes > ceiling ${LIMIT} bytes"
|
|
fi
|
|
pct=$(( (gz_bytes * 100) / LIMIT ))
|
|
printf ' ✓ gzip size %s bytes (%d%% of %s ceiling)\n' "${gz_bytes}" "${pct}" "${LIMIT}"
|
|
|
|
printf '\nAll Step 1b §6 + §7.1 bundle gates PASS.\n'
|