Releases: vicmaster/framesmith
v1.3.0 — Cliché guardrails + Structured critique
Two phases land in v1.3.0, both built spec-first (docs/specs/PHASE-12-SPEC.md, PHASE-13-SPEC.md).
✨ Phase 12 — Cliché & craft guardrails
canvas_evaluate now scores cliché, not just craft — the visual tells that read as machine-made, all detected on the scene graph (and confirmed against the render).
- New
clichecategory (weight 15), each issue tagged with atell:- default purple/indigo accent · gradient/glow overuse · fake browser/OS chrome (traffic-light dots) · the hanging eyebrow-beside-heading header · fabricated metrics/testimonials/logos (honest-content)
- Mechanical autofixes via
canvas_autofix— swap a known-default purple accent → neutral, delete a fake-chrome strip. Taste tells (gradients, hanging header, fabricated copy) are suggestion-only. - Genre-aware loosening —
genreoption / provenance preset relaxes intentional tells (e.g.materialallows purple).
✨ Phase 13 — Structured critique & auto-revision
The LLM judge (opt-in mode:"llm") moves from one opaque number to a fixed multi-axis rubric, and can now close the loop.
- Rubric: hierarchy · execution · specificity · restraint · variety — each 1–5 with a rationale; derived 0–100 overall.
- Revision threshold: per-axis
floor(default 3,FRAMESMITH_CRITIQUE_FLOOR) →needsRevision+failingAxes. - New
canvas_revisetool: bounded judge → revise failing axes viabatch_designops → re-judge (≤3 passes); stops on pass / cap / no-improvement (reverts regressions) / apply-error. - Verdict stamping:
metadata.critique+ a compact entry on the per-project build log; viewer shows a verdict chip.
⚠️ Breaking change (experimental LLM mode only)
canvas_evaluate with mode:"llm" — the llmCritique shape changed: free-text strengths/weaknesses are replaced by the per-axis rubric (plus needsRevision / failingAxes). All heuristic categories and every other tool are unchanged.
npx framesmith # or
claude mcp add framesmith npx framesmith
Full changelog: v1.2.0...v1.3.0
v1.2.0 — Agent onboarding & dogfooding fixes
This release closes #64 — an onboarding gap plus a batch of bugs found designing a feature end-to-end from a real agent session. All changes are additive; pre-1.2 canvases load unchanged (no migration).
Onboarding
- Server
instructions— framesmith now ships an MCPinstructionsblock, so any client is oriented on connect (the Workspace › Project › Canvas model, the layered$tokensystem, "readframesmith://guidelinesfirst", and current gotchas) with zero tool calls. - New
inittool — one idempotent call to start a session: binds the repo if needed, scaffolds the convention projects (Foundations + UI), and returns the live re-keyed IDs, a workflow cheatsheet, the gotchas, and the viewer URL. The fix for "binding re-keys IDs, so docs go stale instantly." batch_designreturns a{ varName: nodeId }map — map your bound variables straight to created node IDs instead of counting result positions.
Fixes
- A CSS-string
gradient/shadowsno longer crashesscreenshot(structured form stays canonical; strings are accepted). canvas_moveon a bound repo now relocates the canvas file to the target project's directory.canvas_evaluateno longer flags a contrast ratio that rounds to exactly 4.5:1 (rounded to 2 decimals for compare + display).apply_presetpreserves tokens inherited from the workspace/project design system instead of silently overwriting them (reported aspreservedFromDesignSystem).import_design_mdnow reads list / table /name: valuetoken formats per section, honors explicit named spacing instead of injecting a default scale, and documents the accepted schema.
Docs
- A "Sharp edges" section in
framesmith://guidelinesconsolidating the operational caveats; loudercanvas_bindre-key callout.
Install: npx -y framesmith · Upgrade: already on latest.
v1.1.0 — Design variety & anti-sameness
Phase 11 makes framesmith deliberately vary page layouts instead of converging on the same hero-and-three-cards shape every session.
Highlights
- Layout structure library — six named page scaffolds (
marquee-hero,bento-grid,stat-led,editorial-longform,split-workbench,catalogue), each a partial scene tree of labeled placeholders. Distinct from color presets; they compose. list_structures/apply_structure— pick a structure, get a placeholder skeleton to populate, render, and verify. PassprojectIdtolist_structuresfor a diversification signal.- Structure taxonomy — every scaffold is tagged on four independent axes (
heroTreatment,density,rhythm,alignment), so "differs from last time" is computable. - Per-project build log — records the structure / preset / axes behind each canvas, in both the global store and repo-bound
.framesmith/dirs. - Diversification signal —
canvas_create(andlist_structureswithprojectId) surface recent work plus a "differ on ≥ 1 axis" hint when recent canvases converge. Advisory, never blocking. - Provenance — each canvas records what produced it, shown as a chip on the viewer detail page.
Upgrading from 1.0.0
- Additive — no migration, no data risk. Existing canvases load unchanged (provenance is optional); build-log files are created lazily on first use. Forward- and backward-compatible.
- Existing canvases simply have no provenance until you apply a structure/preset to them; their projects' diversification signal starts empty.
- To get 1.1.0: update via
npx framesmith@latest(or clear the npx cache) and restart your MCP client so it loads the new version.
Full changelog: v1.0.0...v1.1.0
v1.0.0 — framesmith
First public release. npx framesmith — an open-source MCP server that gives your AI coding agent a visual design canvas: sketch the UI, review it in a browser, agree on the design before any framework code gets written.
Formerly canvas-mcp — renamed to framesmith for v1.0.
Headline: your designs live in your repo
Canvases persist as open JSON in a .framesmith/ directory, checked in alongside your code — committable, diffable in code review, and self-contained on clone. The repo is the source of truth; no proprietary, encrypted store. Bind a workspace with canvas_bind and the server auto-detects it on startup.
What's in 1.0
- Scene graph → HTML/CSS → Puppeteer screenshots — agents author via MCP tools, you review real browser renders.
- Workspaces / projects and a Figma-style standalone viewer (read-only gallery across global + every bound repo).
- Design systems with workspace → project → canvas token inheritance.
- Responsive breakpoints (
stack/wrap/ fluid widths) with true reflow. - Evaluation — heuristic design scoring + optional LLM-as-judge, with auto-fix ops.
- Repo-bound storage — deterministic JSON, asset externalization (
.framesmith/assets/), external-change safety, viewer write-back.
Install
# Claude Code
claude mcp add framesmith -- npx framesmithWorks with any MCP client (Cursor, Windsurf, VS Code, Codex). See the README for per-client config.
MIT licensed.
v0.9.0 — Workspace-level design systems
Tokens declared once, inherited everywhere.
The Coide use case finally clicks: set the design system once on the workspace, every canvas under it resolves $primary / $bg / $lg automatically.
Highlights
Workspace.designSystem+ symmetricProject.designSystem— declare tokens once at the workspace level; projects can override.- Three-layer resolution at render:
canvas.variables(override) →project.designSystem→workspace.designSystem→ built-in defaults. Per-category merge — setting onlycolorsdoesn't resetspacing/radius/typography. - Six new MCP tools:
workspace_set_design_system,workspace_get_design_system,workspace_apply_preset+ symmetricproject_*trio. Presets (dark,light,material,minimal) installable at workspace OR project level. - Shared
getCanvasTokens(canvas)helper insrc/workspaces.ts— every render path (MCP tools, viewer, evaluate, canvas_diff) routes through it. The docstring warns against the anti-pattern that bit us in #40.
Authoring story
// Once per workspace — brand colors set globally
workspace_set_design_system({
workspaceId,
variables: {
colors: { primary: "#0066ff", bg: "#0a0a0a" },
spacing: { sm: 8, md: 16, lg: 24 }
}
});
// Every canvas under that workspace
batch_design({ canvasId, operations: 'I(parent, { fill: "$primary" })' });
// → resolves to #0066ff via workspace inheritance, no canvas-level redefinitionBonus
- Fix #40 — viewer / canvas_diff / evaluate were missed in the Phase 9 PR, leaving them with the old
resolveVariables(canvas.root, canvas.variables)bypass. Caught while dogfooding the release page. - Dogfood #41 —
scripts/build-phase9-showcase.tscomposes a single-canvas hero that visually documents canvas-mcp's design system AND proves three-layer inheritance works end-to-end (canvas itself hasvariables: {}— every value resolves from workspace tokens). Plus reorganized canvas-mcp's own dogfood artifacts intoDesign system / UI / Releasesprojects following Figma + atomic design + Spotify Encore conventions.
Backward compatibility
All Phase 9 additions are opt-in:
- Existing canvases without workspace/project
designSystemrender identically — the merge falls through tocanvas.variablesalone. setVariables/getVariables/ canvas-levelapply_presetunchanged.- Workspace/Project JSON gain an optional
designSystemfield; older persisted entries without it load cleanly.
No migration needed.
What's next
Only Phase 10 (Ecosystem — image generation, HTTP transport, VS Code extension, Figma import, marketplace, plugins) remains for the v1.0 push.
v0.8.0 — Renderer expressiveness
The renderer learned how to fade in, blur what's behind it, load a real typeface, draw a custom mark, and know which ancestor to anchor against.
Five primitives that expand what a canvas-mcp design can express. Every item came from a concrete Phase 7 slice-5 design moment the renderer couldn't render.
Highlights
- Auto
position: relative— frames automatically receiveposition: relativewhen a descendant usesposition: absolutewithout a positioned ancestor. Fixes the slice-5a "absolute child escapes to body coordinates" bug. (#31) - Custom fonts —
set_fonts/get_fontsMCP tools. Renderer emits@font-face+<link rel="preconnect">per origin +font-display: swap. (#32) backdropFilter— structured object withblur/saturate/brightness/contrast. Bothbackdrop-filterand-webkit-backdrop-filteremitted for Safari. LegacybackdropBlurstill works. (#33)pathnode type — custom SVG marks via rawd+viewBox. Fill/stroke apply to the path element (not the wrapper). Tight character whitelist ond. (#34)- Animations — structured
animationfield referencing built-in keyframes (fadeIn,slideUp,slideDown,scaleIn).@keyframesauto-emitted only when referenced. Structuredtransitionready for future hover/JS state changes. (#35)
Bonus
- Inline style escape fix —
"and&in CSS values now HTML-escape correctly. Found while dogfooding the release page withfontFamily: '"Inter", system-ui, sans-serif'(the inner"was prematurely closing the outerstyle="..."attribute). (#36) - Dogfood release page — single-canvas hero composed via canvas-mcp itself, exercising every Phase 8 primitive. Reproduce with
npx tsx scripts/build-phase8-release.ts, then visit/canvas/phase8-releasein the viewer to see animations play. (#37)
Backward compatibility
All Phase 8 additions are opt-in:
- Existing canvases without
fonts/animation/transition/backdropFilter/pathnodes render identically. - The legacy
backdropBlur: numberfield keeps working unchanged. - Auto
position: relativeonly applies via external stylesheet rule, so inlinepositiondeclarations always win. - The renderer escape fix is invisible to canvases that didn't trip the bug.
No migration needed.
What's next
Phase 9 — Workspace-level design systems. Promote per-canvas variables to workspace-inherited tokens with explicit per-canvas overrides. "Every Coide canvas should follow Coide's design system without redefining colors per canvas."
v0.7.0 — Workspace UI overhaul
canvas-mcp grows up from a flat dashboard into a real workspace. Workspaces → Projects → Canvases hierarchy on the MCP side, a Figma-style viewer with sidebar navigation and archive surface, and a visual refresh that drops the AI-default purple for a flat amber identity.
Highlights
- Hierarchy —
workspace_create/project_create/canvas_moveand friends. 11 new MCP tools let the AI organise canvases without the user touching the filesystem. - Sidebar viewer — workspaces and projects in a collapsible left sidebar, project-scoped main pane with breadcrumb, archive surface for soft-deleted canvases with restore + permadelete actions.
- Visual refresh — flat amber accent on warm-dark surfaces (no gradients, no purple), Linear-style restraint executed with a distinct identity. Cards get glass-rim shadows, empty thumbnails get the "layered canvas" treatment, detail toolbar groups buttons into clusters with hairline dividers.
- Mobile — sidebar collapses to an off-canvas drawer below 768px; detail toolbar stacks clusters into full-width rows with proper touch targets.
- Migration — existing canvases auto-gain a
projectIdon first load and land in the defaultPersonal / Untitledbucket. No manual intervention.
What's in this release (10 PRs)
- #21 Roadmap for Phase 7 added
- #22 Slice 1 data model + migration
- #23 Slice 2 workspace/project CRUD + canvas lifecycle MCP tools
- #24 Slice 3 empty thumbnail placeholder
- #25 Slice 4a sidebar + project-scoped main pane
- #26 Slice 4b archive surface + lifecycle UI
- #27 Slice 5a dogfood mock for the visual refresh
- #28 Slice 5b implementation (flat amber palette, mobile drawer, toolbar clusters)
- #29 Phase 7 closeout + Phase 8/9 roadmap added
- #30 Version bump
Backward compatibility
Existing canvas files gain "projectId": "default-project" on first load — one-shot rewrite, idempotent on subsequent runs. The MCP server adds 11 tools but doesn't change any existing tool surface. canvas_create and canvas_list are backward-compatible (new parameters are optional with sensible defaults).
What's next
Phase 8 (Renderer expressiveness) — backdrop-filter, custom font loading, SVG paths, animations. Every item came from a concrete slice 5 design moment the renderer couldn't express.
v0.6.0 — Evaluation & AI Loops
Phase 6 closes the generator-evaluator loop. canvas_evaluate now ships alongside a benchmark suite that catches scoring drift, a canvas_autofix tool that returns mechanical fixes as ready-to-run batch_design ops, and an opt-in LLM-judge mode that brings a vision model's holistic critique alongside the deterministic heuristics.
Highlights
canvas_autofixreturns the subset ofcanvas_evaluateissues that have a mechanically derived fix — off-scale spacing snaps to scale, multi-child frames withoutlayoutgetvertical, recoverable WCAG contrast failures get#000or#FFFbased on background luminance. Each fix is a ready-to-pastebatch_designUpdate op. Closes the loop without judgement calls.- LLM-judge mode —
canvas_evaluate({ mode: "llm" })runs the fast heuristics and adds anllmCritiquefield (score / summary / strengths / weaknesses / suggestions). Pluggable provider table: Anthropic Claude and OpenAI GPT shipped, third provider is one entry insrc/llm-judge.ts. Provider picked fromCANVAS_LLM_PROVIDERenv var or whichever API key is set. - Benchmark suite —
npm run benchrunscanvas_evaluateover a fixed corpus (hero,minimal,bad-contrast) and diffs againstbenchmark/baselines.json. Detects drift inoverallScore, per-category scores, issue counts, and issue messages. Re-baseline withnpx tsx benchmark/run.ts --update.
What's in this release (4 PRs)
- #17 Benchmark suite + drift-detecting runner
- #18
canvas_autofixwith mechanical fixes for spacing, layout, contrast - #19 LLM-judge mode (pluggable Anthropic / OpenAI)
- #20 Version bump
Backward compatibility
EvaluationResult.mode extends to 'fast' | 'detailed' | 'llm'; all new fields are optional. Heuristic-only callers see no breaking change. The benchmark runner uses fast mode, so adding llm does not affect existing baselines.
v0.5.0 — Responsive Layout
canvas-mcp is an open-source MCP server that gives any AI assistant a visual design canvas. This release makes canvases actually adapt across breakpoints instead of just rescaling.
Highlights
responsivehint on containers (stack/wrap/fixed) — author desktop-first, the renderer derives the mobile layout from the same scene graph.- Fluid widths —
width,minWidth,maxWidthaccept percentages,fit-content, and other CSS lengths so designs flex within bounds. - True reflow everywhere —
screenshot_responsivenow re-renders per breakpoint, and the viewer has a new Compare mode showing mobile / tablet / desktop side-by-side, each at its real viewport. - Authoring guidelines as an MCP resource (
canvas-mcp://guidelines): width strategies, common patterns, anti-patterns. - Renderer polish — system sans-serif default, root document fills + centers the viewport on wide screens,
batch_designparser handles embedded'Segoe UI'-style strings.
What's in this release (9 PRs)
- #6
responsivehint + renderer mapping - #7 Fluid widths (
minWidth/maxWidth) - #8 README hero composed via canvas-mcp itself
- #9 Default sans-serif at the renderer level
- #10 Root document fills + centers viewport
- #11 Quote-aware
batch_designparser - #12
canvas-mcp://guidelinesMCP resource - #13
screenshot_responsivetrue reflow - #14 Viewer Compare view
- #15 Version bump
Still open
- Phase 5 #8 (stretch) — per-breakpoint override map as opt-in escape hatch. Deferred by the original design memo.
- 768px breakpoint boundary fix (next PR after this tag).

