Commit Graph

22 Commits

Author SHA1 Message Date
069ea1235a sitesmith: null-safe esc() across all toHtml + WorkingIndicator
Real-world AI output frequently sends mismatched prop names (e.g.
items vs features, cta object vs buttonText/Href). The toHtml functions
of section/form/sections-folder components each defined a local
esc = (s: string) => s.replace(...) that crashed when called with
undefined, taking the auto-save export with it.

Patched every local esc() to coerce non-strings:
  const esc = (s: any) => String(s ?? "").replace(...)
17 files touched; behavior unchanged for valid string inputs.

Also adds a WorkingIndicator (Claude Code-style spinner + rotating
phrase + elapsed seconds) shown in the modal footer while a generation
is in flight, replacing the disabled "Thinking..." placeholder.
2026-05-24 15:54:48 -07:00
ac0347ae5f sitesmith: fix blank canvas on Replace site
treeToState() was setting isCanvas:true on every node, including leaf
components (Heading, TextBlock, ButtonLink, Spacer, ImageBlock). Craft.js
then renders those as empty drop-canvas wrappers instead of their actual
content, so the canvas appears blank after applying an AI-generated
'replace' response.

Now uses a CANVAS_TYPES set matching the apply-ai-response utility:
only the layout wrappers (Container, Section, ColumnLayout, Hero/Features/
CTA sections, FormContainer, Navbar, Footer, etc.) are canvases. ROOT is
forced to be a canvas regardless of source type so children render.

Also defensively normalizes props.style: AI sometimes emits an empty
array instead of an object, which can confuse downstream consumers.
2026-05-24 15:35:05 -07:00
5c5066c20b Merge pull request 'Sitesmith: AI site builder addon (frontend)' (#1) from sitesmith-ai-builder into main
Reviewed-on: #1
2026-05-24 17:11:03 +00:00
0f943bacc7 sitesmith: playwright e2e suite (locked/cap/bonus/build+patch)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 14:27:34 -07:00
2ca1ff0cf9 sitesmith: layers panel prefers props.aiName when present 2026-05-23 14:25:43 -07:00
e651becdbe sitesmith: chat modal (messages, input, banner, scope confirm) 2026-05-23 14:25:28 -07:00
b4d71340e1 sitesmith: upgrade banner + scope-replace confirmation dialog 2026-05-23 14:24:20 -07:00
bf55ee85b9 sitesmith: topbar button with locked/capped states 2026-05-23 14:23:51 -07:00
cf3457aa15 sitesmith: apply-ai-response utility (replace + patch + ask) + PageContext helpers
Add apply-ai-response.ts with serializeTreeForCraft, buildNodeTree, findNodeIdByAiNodeId,
and useApplyAiResponse hook covering replace (site/page/section), patch (5 ops), and ask.
Extend PageContext with replaceAllPages, replaceCurrentPage, setHeader, setFooter helpers
that mirror the existing actions.deserialize/loadState pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 14:20:51 -07:00
f6243d3ffe sitesmith: useSitesmith hook (entitlement, history, send) 2026-05-23 14:16:20 -07:00
8d094a9c67 sitesmith: typescript types for messages, responses, patch ops 2026-05-23 14:15:15 -07:00
14a957f57c sitesmith: canvas summary serializer with unit tests 2026-05-23 14:14:38 -07:00
bd15a33984 sitesmith: harden HtmlBlock with DOMPurify + add Vitest setup
Closes XSS hole in HtmlBlock by sanitizing user/AI-supplied markup
through DOMPurify before passing to dangerouslySetInnerHTML. Adds
Vitest + jsdom for unit testing with 5 passing tests covering script
stripping, on-event handler removal, javascript: URL blocking, iframe
allowlist, and form/input stripping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 14:13:42 -07:00
606c9b78c8 fix(image-radius): split out 3x-scale IMAGE_RADIUS_PRESETS for the image picker
Image radii need to be visibly larger than the radius scale that works for
buttons/containers — at typical photo dimensions, 16px reads as nearly
square. Add an image-specific scale at 3x the shared values (S=24px,
M=48px, L=96px) and route ImageStylePanel through it. Other components
(buttons, sections, containers) keep RADIUS_PRESETS unchanged.

Note: this commit also bundles unrelated pre-existing working-tree changes
in the legacy GrapesJS site-builder root (CLAUDE.md, index.html,
css/editor.css, js/assets.js, js/editor.js, js/whp-integration.js) that
were inadvertently picked up by an earlier `git add -u`. The image-radius
change is the only intentional content of this commit; the rest is
in-progress legacy work that happened to be sitting uncommitted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 05:18:31 -07:00
8eeaecd857 fix(radius): bump shared RADIUS_PRESETS so S/M/L are visible on real elements
The actual radius picker shown to users for images, sections, and
containers comes from ImageStylePanel etc. via the shared
RADIUS_PRESETS — not from each component's own settings panel. Earlier
fix only bumped ImageBlock's local scale, which is a different control.

Bump shared scale: S=8px, M=16px, L=32px, Full=9999px (unchanged).
Existing saved sites are unaffected — only future preset clicks pick
up the new values.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 21:22:57 -07:00
c2bacb41bf feat(image): bump radius presets so S/M/L are actually visible on real images
4px and 8px were imperceptible on typical image sizes. New scale
0/8/16/32/50% gives visible steps for None/S/M/L and keeps Full as
round.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 21:05:25 -07:00
1558626b84 fix(delete): redirect Delete to owning component when target is empty linked node
Linked Craft.js nodes (column children of ColumnLayout, section-inner of
Section, etc.) are structurally non-deletable — actions.delete throws and
the error was silently swallowed. Empty layouts ended up undeletable from
the canvas because clicks always landed on the linked children that fill
the layout's visible area.

Adds findDeletableTarget(): when target is a linked node and ALL its
linked siblings are also empty (i.e., the layout itself is empty),
redirect deletion to the owning parent. Refuses to redirect when any
sibling has content, to protect against nuking a 3-col layout that has
content in other cols.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 20:42:17 -07:00
4acbeefaed fix(container): align block children when Content Alignment is set
textAlign only affects inline content, so block children like ImageBlock
(display:block, width:100%) ignored it. Switch to flex-column with
align-items mapped from textAlign whenever alignment is set; layout is
unchanged when alignment is unset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 20:24:28 -07:00
91a6b6f34b Add Craft.js site builder (v2) - complete rebuild from GrapesJS
Rebuilt the visual site builder from scratch using Craft.js, React 18,
and TypeScript. The new editor renders directly in the DOM (no iframe),
supports 40+ components, multi-page with shared header/footer, 16
templates, full-spectrum color/gradient controls, custom head code
injection, save/publish workflow, and auto-save.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 18:31:16 -07:00
b511a6684d Add templates, tests, and miscellaneous project files
Includes new page templates (fitness-gym, nonprofit, online-course,
photography-studio, real-estate, startup-company, travel-blog,
wedding-invitation) with thumbnail SVGs, test specs, documentation
files, and minor updates to index.html, router.php, and playwright config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:15:58 -08:00
03f573b451 Replace Google Docs viewer with download card for non-PDF file embeds
PDF files continue to embed in an iframe. Non-PDF files (DOC, DOCX, XLS,
etc.) now show a download card with the file name and download icon instead
of relying on Google Docs Viewer, which often fails with "No preview
available."

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:13:02 -08:00
a71b58c2c7 Initial commit: Site Builder with PHP API backend
Visual drag-and-drop website builder using GrapesJS with:
- Multi-page editor with live preview
- File-based asset storage via PHP API (no localStorage base64)
- Template library, Docker support, and Playwright test suite

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:25:42 +00:00