webcake-landing-mcp 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,6 +43,12 @@ CENTERING & ALIGNMENT (do the math — do NOT eyeball \`left\`; off-center layou
43
43
  - Keep a consistent left edge for stacked content in a section (e.g. all centered on the same axis) so the section reads as aligned, not ragged.
44
44
  - Mirror the centering on BOTH breakpoints with each breakpoint's own canvas width — never reuse a desktop \`left\` on mobile.
45
45
 
46
+ STICKY / FIXED HEADER (and any overlay element) — reserve space so nothing hides behind it
47
+ - A sticky/fixed header (set via the per-breakpoint config.sticky on the section) OVERLAYS the page; it does NOT push the sections below it down. So the next section's top content sits UNDER the header and gets hidden — this is the #1 header defect.
48
+ - When you add a sticky header of height H (typically 60–72px): push the first section's top content DOWN by ≥ H — increase the \`top\` of the hero's topmost elements by H (and add H to that section's height so the band stays clear), OR keep an empty H-px band at the very top of the hero. Do it on BOTH breakpoints (the header height can differ per breakpoint).
49
+ - Do NOT duplicate the brand/shop name: if the header shows the shop name, remove or reposition any shop-name line that sat at the very top of the hero — otherwise the two overlap (a classic symptom: a half-hidden shop-name behind the header).
50
+ - A NON-sticky header is simpler — it's just the first section in \`page\`, stacks normally, and pushes the hero down on its own (no offset needed). Only add the offset when the header is sticky/fixed.
51
+
46
52
  RULES
47
53
  - Visible content goes in "specials" (text-block.specials.text, image-block.specials.src…), NEVER in "styles".
48
54
  - Colors as rgba(r,g,b,a). fontSize/borderWidth/top/left/width/height are NUMBERS (px).
@@ -52,21 +58,22 @@ RULES
52
58
  - Every form input MUST have a unique specials.field_name.
53
59
  - events item: { "id", "type", "action", "target", ...action-specific extra fields }. TRIGGER (type): click & hover on any element; success & error on a FORM (success = after a successful submit, error = on validation failure); delay on any element (when it scrolls into view); unset on init. Action vocab per trigger: click→CLICK_ACTIONS, hover→HOVER_ACTIONS, success→SUCCESS_ACTIONS, error→ERROR_ACTIONS, delay→DELAY_ACTIONS (all returned by get_generation_guide). For element-targeting actions (open_popup, close_popup, scroll_to, show_section, hide_section, show_hide_element, change_tab, collapse) target = the target element's id; open_link/download_file target = URL; open_sms/send_email/phone_call target = phone/email; copy target = text (or element id when copyType='elementValue'); set_field_value target = field_name; target may be null (e.g. animation_hover). Each action also reads extra fields (e.g. open_link→targetURL/delayTime, scroll_to→scrollMore, change_tab→moveTo/tabIndex, lightbox→typeLightbox/alt, show_hide_element→onlyMode, open_app→appTarget+provider fields, set_field_value→set_value) — see the action maps for the full list.
54
60
  - ANIMATION: each breakpoint's config has config.animation = { "name":"none", "delay":0, "duration":3, "repeat":null }. Keep "none" unless an entrance animation is wanted.
55
- - Do NOT invent prices, phone numbers, addresses, or statistics. Output text in the requested language.
61
+ - Real data the page DISPLAYS must come from the user — never invent it: phone/hotline/Zalo, price (+ original price), address, shop/brand name, links/URLs, email, opening hours, exact stats/social-proof numbers. If a value the page needs is missing, ASK for it (in intake, or pause before generating); use a clearly-labelled placeholder ONLY when the user explicitly declines, and tell them exactly what to fill. Output text in the requested language.
56
62
 
57
- INTAKE — ask the user BEFORE generating (don't assume; ask 3–6 short, concrete questions, offer sensible defaults):
58
- - Goal / page type: lead-gen, product/COD sale, event, invitation, app promo, portfolio…?
59
- - Brand: name, what they sell, tone (premium/playful/minimal), language (vi/en…).
60
- - Sections wanted (in order): e.g. hero, features, pricing, testimonials, FAQ, contact form, footer.
63
+ INTAKE — ask the user BEFORE generating, EVERY time (even a "quick"/"test" page). The #1 mistake is building a full page on the first message without asking — do NOT do that. Ask ONE short batch of 3–6 concrete questions (offer sensible defaults so the user answers fast), enough to understand the page's purpose, name, look and layout:
64
+ - Goal / page type: what is the page FOR? lead-gen, product/COD sale, event, invitation, app promo, portfolio, a test/demo…?
65
+ - Brand: page/shop name, what they sell, tone (premium/playful/minimal), language (vi/en…).
66
+ - Product + price (sales/ads pages): the exact product, price (+ original price if discounted), and the offer/promo.
67
+ - Sections wanted (in order): e.g. hero, features, pricing, testimonials, FAQ, contact form, footer — or propose a sensible default set and ask the user to confirm.
61
68
  - Primary CTA + where it goes: open a form popup, scroll to form, call/Zalo, open link?
62
69
  - Form fields to capture (if any): name, phone, email, address, quantity…? (use canonical field_names: full_name, phone_number, email, address, quantity).
63
- - Branding details: primary color (rgba/hex), logo/image URLs, must-keep text, things to avoid.
70
+ - Branding / look: primary color (rgba/hex), logo/image URLs, must-keep text, things to avoid.
64
71
  - Target: desktop+mobile or mobile-only? Which organization to save into (list_organizations)?
65
- Confirm a short outline (sections + CTA) with the user before building the full JSON.
66
- NEVER invent prices, phone numbers, addresses, or statistics — ask or leave placeholders the user can fill.
72
+ Then RESTATE a short outline (sections + CTA + colors) and WAIT for the user's confirmation before assembling the JSON. Do NOT generate + persist on the same turn as the request.
73
+ NEVER invent prices, phone numbers, addresses, or statistics — ask, or leave a clear placeholder ONLY when the user declines to provide it.
67
74
 
68
75
  WORKFLOW (recommended)
69
- 0. INTAKE: ask the questions above, confirm the section outline.
76
+ 0. INTAKE (never skip — even for a quick/test page): ask the essentials above, WAIT for the answers, restate a short outline (sections + CTA + colors), and get the user's "yes" BEFORE any new_page_skeleton / create_page. Do not generate on the same turn as the request.
70
77
  1. Call get_generation_guide (this) once, then new_page_skeleton for the top-level shape.
71
78
  2. For each element type you'll use, call get_element to learn its specials & see an example.
72
79
  3. Optionally call new_element to get a correct skeleton, then fill specials + coordinates.
@@ -6,8 +6,8 @@
6
6
  export const INSTRUCTIONS = `webcake-landing builds and edits Webcake landing pages (the editor "page_source" JSON).
7
7
 
8
8
  RULES (follow for every request):
9
- - INTAKE FIRST: before generating a new page, ask the user 3–6 concrete questions (goal/page type, brand + tone + language, sections in order, primary CTA + destination, form fields, colors/logo URLs, desktop+mobile or mobile-only, which organization) and confirm a short outline. Do not assume.
10
- - Never invent prices, phone numbers, addresses, or statistics ask or leave a placeholder.
9
+ - INTAKE FIRST do this EVERY time, even for a "quick"/"test" page. Do NOT jump straight to new_page_skeleton/create_page on the same turn as the request: ask the essentials, restate an outline, get a "yes", THEN build. Ask ONE short batch (3–6, with sensible defaults so the user answers fast) enough to understand the page's PURPOSE, name, look and layout: page purpose/goal, brand/page name, what they sell + price (sales/ads pages), primary color + logo/branding, sections & layout in order, primary CTA + destination, desktop+mobile or mobile-only, which organization. Then restate a short outline (sections + CTA + colors) and WAIT for the user's confirmation before generating. Never assume or silently placeholder the page name, product, price, or colors — ask; only placeholder a core fact when the user explicitly declines to give it.
10
+ - ASK for any real data the page will display — never invent it, and don't silently placeholder it. This includes: phone/hotline/Zalo, price (+ original price), address, shop/brand name, links/URLs, email, opening hours, and exact stats/social-proof numbers. If a value the page needs is missing, ASK the user for it (in intake, or pause and ask before generating). Use a clearly-labelled placeholder ONLY when the user explicitly says to skip it — then tell them exactly what to fill in.
11
11
  - ALWAYS call validate_page and fix every error before create_page / update_page.
12
12
  - create_page and update_page DEFAULT to dry_run=true. Show the dry-run, then only send dry_run=false after the user confirms.
13
13
  - EDIT existing pages surgically: get_page → change ONLY what was asked → keep every other element, its id, and coordinates → validate_page → update_page. Never regenerate the whole tree for a small change.
@@ -17,6 +17,7 @@ MODEL (essentials):
17
17
  - Top-level: { page:[sections], popup:[popups], settings:{}, options:{currency,mobileOnly,versionID}, cartConfigs:{} }. Popups are a SEPARATE top-level array, NOT inside page.
18
18
  - Element: { id, type, properties, responsive:{desktop,mobile:{config,styles}}, specials, children, runtime, events }. Absolute canvas: children carry numeric top/left/width/height (px) per breakpoint (canvas width desktop=960, mobile=420); sections own a height.
19
19
  - CENTERING (the #1 layout defect — do the math, don't eyeball): to center a box compute left = round((canvas - width)/2) — 960 desktop, 420 mobile. textAlign:center only centers text inside the box, not the box itself. For a row of N items, center the whole row block (startLeft = round((canvas - (N*item + (N-1)*gap))/2)). Keep 0 ≤ left and left+width ≤ canvas on each breakpoint.
20
+ - STICKY HEADER: a sticky/fixed header (config.sticky) OVERLAYS the page — it does NOT push sections below it down. Offset the first section's top content DOWN by the header height (~60–72px) so nothing hides behind it, and do NOT duplicate the shop name in both the header and the top of the hero. A non-sticky header stacks normally and needs no offset.
20
21
  - Visible content lives in specials (text, src, field_name…), never in styles. Colors as rgba(). Animation in config.animation={name,delay,duration,repeat}. Form inputs need a unique specials.field_name (use canonical keys: full_name, phone_number, email, address, quantity).
21
22
  - IMAGES: include them (hero/product, feature icons, about photo). No image API yet → set image-block specials.src to a PLACEHOLDER sized to the box: https://placehold.co/<width>x<height> (gallery.media = array of these; video.specials.img = poster). NEVER leave src empty (renders blank). Ensure text contrasts with its section background.
22
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webcake-landing-mcp",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "MCP server exposing Webcake landing-page element schemas + AI usage hints, and persisting LLM-generated page sources to a Webcake backend.",
5
5
  "type": "module",
6
6
  "bin": {