Commit Graph
418 Commits
Author SHA1 Message Date
shadowdaoandClaude Opus 5.5 4a34781ab6 Sitesmith cleaner: patches use the target component's rules; CSS values checked against a positive grammar
Review findings on clean-ai-response.ts:
1. update_props is now cleaned with the TARGET node's component (resolved on the
   live canvas by apply()); an unresolvable target gets the strictest rules
   (no code, url/src only assets/). code is kept only on an HtmlBlock.
2. cssValueAllowed() is a positive grammar: numbers/lengths/hex/keywords, an
   allow-list of functions (gradients, colour functions, calc/clamp, var(--*),
   transforms, filters), url() only of assets/<file>, quoted strings only plain
   font names; image-set(, src(, cross-fade(, element(, paint(, attr(, env(,
   ':' or '//' outside url(assets/..), backslashes and control chars rejected.
   Regression: every style/colour value in the templates, section families and
   palettes passes (clean-ai-response.ordinary.test.ts).
Also: tricky link forms (//host, backslashes, whitespace/control chars,
mixed-case schemes, > 2048) rejected; comments state the server-side mirror is
not implemented (deferred).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:38:14 -08:00
shadowdaoandClaude Opus 5.5 2b8b0557b2 Sitesmith: allow-list cleaner for model responses before they reach the canvas; export strips attack-only CSS (G8)
clean-ai-response.ts runs first in useApplyAiResponse().apply() and in
applyRegeneratedSection(): link props allow ''|#anchor|relative|mailto:|tel:|
https:|http: (never //host, backslash, whitespace/control chars, > 2048);
images only assets/<file> or https on images.pexels.com / placehold.co;
videos assets/ or YouTube/Vimeo; the model can never set form destinations,
relay settings or head code (patches keep the user's values); style names
must be CSS identifiers and values may not carry url() (except assets/),
@import, expression(, behavior, -moz-binding, javascript:, < > { } ; \;
anchor ids [A-Za-z0-9_-]. HtmlBlock code keeps its existing sanitisers.
Export boundary: stripLegacyCssVectors() in cssValue/cssPropsToString
(byte-identical for ordinary content: OLS fixture + default design measured).
Server-side mirror not implemented (deferred).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:31:42 -08:00
shadowdaoandClaude Opus 5.5 93b3cc35af Colour e2e: baseline commit overridable (COLOR_BASE_COMMIT)
On the release branch mobile-parity's <=767px head rules land before the
colour merge, so 'identical to ab7a100' cannot hold; run with
COLOR_BASE_COMMIT=<commit before the colour merge> there. Measured: vs ab7a100
the only difference is those two documented rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:23:17 -08:00
shadowdaoandClaude Opus 5.5 a113f25a62 Guard test: the capture-frame exception now fails on allow-scripts, a skipped or ignored sanitiser, or src= (G7)
captureFileViolations() pins the one allow-same-origin srcdoc frame: sandbox set
once to exactly allow-same-origin, no script/form/popup/navigation tokens,
srcdoc only from inlineResources(clean.html), sanitizeCaptureHtml called and its
verdict checked before srcdoc. Eight mutated copies of the real source prove
each rule fails. Plus a behavioural jsdom test of the real captureHtml frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:10:30 -08:00
shadowdaoandClaude Opus 5.5 6c406ca99b Sitesmith: self-review is intent 'review' (not a mockup); typed statuses with specific messages (G3, G6)
- The self-review follow-up sends intent:'review' + review_image_ids instead of
  putting the render in mockup_ids, so the backend builds a critique+patch
  instruction instead of 'build toward this mockup'. Render still deleted after.
- types/sitesmith.ts: SitesmithStatus = server statuses (adds IMAGES_BUSY,
  TOO_MANY_JOBS, SERVER_BUSY, ...) + client statuses (TIMEOUT, ABORTED, ...);
  network status strings are narrowed with a type guard (unknown -> ERROR);
  the hook builds SendResultErr without casts.
- statusMessages.ts: one specific message per status (a Record over the union,
  so a new status without a message fails tsc), used by the modal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:10:30 -08:00
shadowdaoandClaude Opus 5.5 7a58921ba3 Sitesmith design payload: brand colours carry their published slot (G1)
buildDesignPayload numbered brand colours by list position while the page
publishes them as --wsb-brand-<slot>, so the prompt could name a different
colour than the page renders. It now uses publishedBrandSwatches (same rule as
the publisher) and sends {name?, hex, slot}.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:10:30 -08:00
shadowdaoandClaude Opus 5.5 3413c7816d Head parity: re-pin E_brand_swatches after the mobile-parity merge
The colour branch pinned the brand head before the <=767px stacking/nav-wrap
rules existed; the bytes are now copied from the merged WHP
generateCompiledHTML output (WHP release/sitesmith-colors).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:56:02 -08:00
shadowdaoandClaude Opus 5.5 9f48b8b134 Merge feat/sitesmith-catalog into release/sitesmith-colors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:55:05 -08:00
shadowdaoandClaude Opus 5.5 ae092990ca Merge feat/sitesmith-ui into release/sitesmith-colors
Conflict: craft/package.json scripts (kept mobile, colour and sitesmith e2e entries).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:55:05 -08:00
shadowdaoandClaude Opus 5.5 57734fbe51 Merge feat/sitesmith-hook into release/sitesmith-colors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:54:46 -08:00
shadowdaoandClaude Opus 5.5 6decf8cdb0 Merge feat/color-system into release/sitesmith-colors
Conflicts: package.json (kept both test:browser:mobile and the colour scripts);
head-parity test (kept E_icons from mobile-parity/main AND the E_brand_swatches /
F_swatches_no_brand cases from color-system; pinned bytes re-derived later
against the merged WHP script).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:54:46 -08:00
shadowdao f6b90d393f Merge fix/mobile-parity into release/sitesmith-colors 2026-11-01 10:54:16 -08:00
shadowdaoandClaude Sonnet 5.5 cfa8ab2e40 Sitesmith modal: load assets once; clearer oversize-image message
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:52:56 -08:00
shadowdaoandClaude Sonnet 5.5 304850fcd3 Sitesmith e2e: Firefox + Chromium end-to-end test of the modal (npm run test:browser:sitesmith)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:48:12 -08:00
shadowdaoandClaude Sonnet 5.5 a406daae1e Sitesmith e2e: reusable mock editor + Sitesmith backend server for real-browser tests
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:48:12 -08:00
shadowdaoandClaude Sonnet 5.5 8a481a87d8 Sitesmith modal: flow tests (phases, cancel, resume, errors, vision off, sites/assets payload, self-review round trip)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:43:23 -08:00
shadowdaoandClaude Sonnet 5.5 784d85346e Sitesmith: tests for payload, design, attachments, panels, self-review runner
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:40:55 -08:00
shadowdaoandClaude Sonnet 5.5 79159dcb28 Sitesmith modal: live job status, cancel, resume, attachments, Sites I like, asset awareness, self-review toggle, design in the request
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:39:47 -08:00
shadowdaoandClaude Sonnet 5.5 f0b3dd1dba Sitesmith capture: CSS judged via CSSOM (no regex), single URL gate (no % / dot segments / backslash), all resources inlined through a bounded no-credentials fetch, CSP img-src data: only; bypass-class proof tests (unit + Firefox/Chromium)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:37:56 -08:00
shadowdaoandClaude Sonnet 5.5 c4f45541a3 Sitesmith: contrast repair wired into apply-ai-response; scoped guard exception for the script-less capture frame
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:32:50 -08:00
shadowdaoandClaude Sonnet 5.5 197b9c46ab Sitesmith self-review capture: sanitise page HTML before it reaches the frame (inert DOMParser allow-list, fixed-point guard), CSP + script-less sandbox, real-browser hostile-page proof; UI building blocks (attachments, sites I like, asset awareness, design payload)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:31:29 -08:00
shadowdaoandClaude Sonnet 5.5 0fde4dc22f Sitesmith: contrast auto-repair for model responses; capture module (html-to-image) for self-review
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:23:26 -08:00
shadowdaoandClaude Sonnet 5.5 7627be78dc SwatchManager chooser: readable text colour and a visible chip border on dark colours
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:12:58 -08:00
shadowdaoandClaude Sonnet 5.5 75bd5921da Real-editor colour-system e2e (Firefox + Chromium): hex entry, pick from page/image, palette, persistence, brand recolour canvas==frontend==backend, caps, contrast
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:12:38 -08:00
shadowdaoandClaude Sonnet 5.5 c4b6802cab Add real-browser mobile parity test (Firefox + Chromium, 390/1280)
npm run test:browser:mobile; MOBILE_PARITY_RECORD/BASELINE compare desktop boxes against a base-commit snapshot.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:10:15 -08:00
shadowdaoandClaude Sonnet 5.5 2e5492600e Editor: mirror default mobile column stacking (canvas emulation + Stack toggle)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:10:15 -08:00
shadowdaoandClaude Sonnet 5.5 69fd34bd7c Preview/Published head: stack ColumnLayout on phones, wrap Navbar links, emit Font Awesome
- <=767px: [class^=cols_] wrappers (every ColumnLayout split) stack; a mobile flexDirection:row override still opts out.
- <=767px: navbars without a hamburger wrap instead of overflowing.
- wrapInDocument emits the same Font Awesome links as the backend sb_font_awesome_link (Preview is a sandboxed srcdoc iframe).
- head-parity pins updated (+ E_icons case).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:10:15 -08:00
shadowdaoandClaude Sonnet 5.5 79cdd593d9 Navbar: showMobileMenu defaults to true for new Navbars and the seeded header
Existing Navbars (prop absent/false) are untouched: render default and toHtml stay falsy.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:10:15 -08:00
shadowdaoandClaude Sonnet 5.5 501f276746 Colour pick mode: header/footer zone previews (pointer-events:none) are now pickable
Found by the real-editor e2e: picking over the header or its logo box returned the page colour behind it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:09:39 -08:00
shadowdaoandClaude Sonnet 5.5 ba5611c3e3 Inline contrast in Text, Button, Pricing and Nav/Footer panels (effective background from node parents)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:02:57 -08:00
shadowdaoandClaude Sonnet 5.5 dcf9c92fee Site Design panel: Saved colours section + inline contrast on text/muted/link/primary-button
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:01:21 -08:00
shadowdaoandClaude Sonnet 5.5 d83919b89a feat(sitesmith): renderer for Sitesmith responses (repo exporter + Firefox shots); catalog tips for ColumnLayout stacking, Navbar, Footer
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:01:04 -08:00
shadowdaoandClaude Sonnet 5.5 faaa8a87a0 Site Design: SwatchManager (saved colours, brand toggle, guarded delete/un-brand, use-as-site-colour, pick + palette)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:00:51 -08:00
shadowdaoandClaude Sonnet 5.5 c34690d08b Colour fields: hex validation, brand chips, pick tools, save colour, inline contrast prop; gradient parse accepts brand refs
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:58:55 -08:00
shadowdaoandClaude Sonnet 5.5 150c84065b TokenSwatchRow: saved colours after the site tokens (brand = live ring + token ref)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:57:17 -08:00
shadowdaoandClaude Sonnet 5.5 9c61f41079 Site colours: replaceBrandRef + PageContext siteStateStrings/rewriteSiteStates for brand-ref rewriting
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:56:55 -08:00
shadowdaoandClaude Sonnet 5.5 2f5c311118 Sitesmith hook: start+poll transport, failure-safe results, refs/assets wrappers
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:54:55 -08:00
shadowdaoandClaude Sonnet 5.5 179aaebe49 Colour picking: native EyeDropper + in-canvas pick mode with brand/token matching, real-browser e2e
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:54:33 -08:00
shadowdaoandClaude Sonnet 5.5 54920dff08 Site colours: pick-from-image and palette-from-image modals
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:53:13 -08:00
shadowdaoandClaude Sonnet 5.5 e4ba07b47e ContrastNote: inline low-contrast hint with suggestion
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:53:05 -08:00
shadowdaoandClaude Sonnet 5.5 de240eee75 feat(sitesmith): catalog generator from real component/section/template definitions + drift test
craft/scripts/gen-sitesmith-catalog.mjs emits a compact JSON catalog (props with
TS types/enums/defaults, token-aware colour props, animation + icon support,
child rules, section recipes, templates, palettes) for the WHP panel prompt.
src/sitesmith/catalog.drift.test.ts regenerates and compares to the committed
whp file so drift fails.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:52:49 -08:00
shadowdaoandClaude Sonnet 5.5 453268a31c Publish checks: button + site-level contrast via checkContrast, unchecked info line
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:52:44 -08:00
shadowdaoandClaude Sonnet 5.5 fb9ac0e6c4 Site colours: real-browser check for image sampling + palette (Firefox + Chromium)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:52:40 -08:00
shadowdaoandClaude Sonnet 5.5 39e954bd77 Contrast: pure WCAG checkContrast/suggestFix/siteColorPairs
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:51:57 -08:00
shadowdaoandClaude Sonnet 5.5 e09a87d2a6 Site colours: palette extraction + same-origin image sampling utils
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:51:47 -08:00
shadowdaoandClaude Sonnet 5.5 1190a98265 tokens: isTokenRef accepts brand token names (digits)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:51:32 -08:00
shadowdaoandClaude Sonnet 5.5 c388be7fe7 Head parity: pin brand-colour swatch cases (E, F) from the WHP script
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:50:25 -08:00
shadowdaoandClaude Sonnet 5.5 faecc76384 Site colours: saved swatches + live brand-colour tokens in design model
design.swatches [{id,label,hex,brand,slot}]; brand ones are published as
--wsb-brand-N appended inside :root (canvas and export share buildTokenVarDecls).
Sites without brand colours emit identical bytes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:49:53 -08:00
shadowdao ab7a10073b Merge fix/editor-parity into release/editor-parity (on top of captcha + Font Awesome) 2026-11-01 09:26:21 -08:00
shadowdaoandClaude Sonnet 5.5 ae02eb7d0d test(site-builder): parity harness neutralises documented editor-only differences (empty drop zone, empty-image placeholder)
Container marks the applied drop zone with data-wsb-dropzone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 09:18:29 -08:00