-
Notifications
You must be signed in to change notification settings - Fork 0
feat: LMX skill #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+606
−0
Merged
feat: LMX skill #15
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| --- | ||
| name: lmx | ||
| description: > | ||
| Use this skill whenever the user wants to create, write, generate, or edit | ||
| email content in Loops. This includes composing campaigns, loops, lifecycle | ||
| emails, transactional email bodies, or any email template for the Loops | ||
| editor or API. LMX (Loops Markup Language) is the format used for all Loops | ||
| email content. Trigger on phrases like "create a campaign", "generate an | ||
| email", "write a welcome email", "draft a lifecycle email", "build an email | ||
| template", "write a transactional email body", "create an onboarding email", | ||
| "LMX", "Loops email", or any request to produce or modify email body content | ||
| intended for Loops. Do not trigger for questions about the Loops HTTP API, | ||
| SDK integration, or CLI unless email body content is also involved. | ||
| metadata: | ||
| version: 1.0.0 | ||
| --- | ||
|
|
||
| # LMX Skill | ||
|
|
||
| This skill helps write, review, and generate correct LMX email markup for Loops. LMX is an XML-based format: every element is a PascalCase tag, self-closing tags require `/>`, and only the tags in the spec are valid. | ||
|
|
||
| ## When To Use | ||
|
|
||
| Use this skill when the task involves: | ||
|
|
||
| - generating or editing LMX email content | ||
| - reviewing LMX markup for correctness | ||
| - choosing the right LMX tags or attributes for a layout | ||
| - applying design guidelines to an LMX document | ||
| - explaining how a specific LMX tag or attribute works | ||
|
|
||
| ## Working Style | ||
|
|
||
| When this skill is active: | ||
|
|
||
| 1. Read `references/lmx-spec.md` for the full tag and attribute reference. It is authoritative — do not invent tags or attributes. | ||
| 2. Read `references/lmx-design-guidelines.md` for Loops design guidelines. Apply these to every document you generate unless the user explicitly overrides a rule. | ||
| 3. Validate nesting and content-type rules before producing output (see spec section 3). | ||
| 4. Check the common-mistakes table in the spec before finalizing output. | ||
| 5. Always produce a complete, valid document — not fragments, unless the user specifically asks for one. | ||
|
|
||
| ## Category Routing | ||
|
|
||
| - Tag definitions, required/optional attributes, nesting rules, content types, variable syntax, self-closing requirements, or escaping: | ||
| Read `references/lmx-spec.md` | ||
|
|
||
| - Color contrast, spacing, column rounded corners, Style tag usage, visual hierarchy, or any "how should this look" question: | ||
| Read `references/lmx-design-guidelines.md` | ||
|
|
||
| ## Output Checklist | ||
|
|
||
| Before returning any LMX output, verify: | ||
|
|
||
| - [ ] All tags are PascalCase and in the allowed set | ||
| - [ ] All self-closing tags use `/>` (e.g. `<Image />`, `<Divider />`, `<Br />`, `<Icon />`, `<Style />`) | ||
| - [ ] No text or inline tags at the top level | ||
| - [ ] Variables use `{name}` syntax and are only inside inline-content tags (not inside `<CodeBlock>` or `<Button>`) | ||
| - [ ] `<For variable="…">` uses braces and contains at least one block child | ||
| - [ ] `<Style />` appears at most once, before all other tags | ||
| - [ ] `bodyColor` and `backgroundColor` are both set on `<Style />` (unless user opted out) | ||
| - [ ] No same-color-on-same-color situations (check text vs block color, icon color vs background, etc.) | ||
| - [ ] Sufficient Y-spacing on block elements | ||
| - [ ] No `blockBorderRadius` applied to items inside `<Columns>` (columns can't be rounded yet) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| # LMX Design Guidelines | ||
|
|
||
| These guidelines apply to every LMX document unless the user explicitly overrides a rule. They cover visual design decisions that the spec does not enforce but that produce good-looking, readable emails. | ||
|
|
||
| --- | ||
|
|
||
| ## Always Set Body And Background Color | ||
|
|
||
| Every document must include a `<Style />` tag with both `bodyColor` and `backgroundColor` set. Do not skip either. | ||
|
|
||
| - `bodyColor` — the email body/card background (the centered content area) | ||
| - `backgroundColor` — the page/canvas behind the body | ||
|
|
||
| Setting both gives the email a clear visual structure and prevents the renderer from falling back to default colors that may clash with your content. | ||
|
|
||
| ```xml | ||
| <!-- Do this --> | ||
| <Style bodyColor="#ffffff" backgroundColor="#f1f5f9" bodyYPadding="24" /> | ||
|
|
||
| <!-- Not this — missing backgroundColor --> | ||
| <Style bodyColor="#ffffff" /> | ||
| ``` | ||
|
|
||
| If the user asks for a dark email: | ||
|
|
||
| ```xml | ||
| <Style bodyColor="#0f172a" backgroundColor="#020617" bodyYPadding="24" /> | ||
| ``` | ||
|
|
||
| Always infer sensible defaults for `bodyYPadding` (typically `"16"` to `"32"`) even when the user doesn't specify. | ||
|
|
||
| --- | ||
|
|
||
| ## Contrast: No Same-Color-On-Same-Color | ||
|
|
||
| Never place text, icons, or UI elements in the same color (or near-same color) as their background. Common failure modes to check: | ||
|
|
||
| **Text vs block/body background:** | ||
| - If `bodyColor` is white (`#ffffff`), `textBaseColor` must be dark (e.g. `#0f172a`, `#1e293b`). | ||
| - If you set `blockColor` on a `<Paragraph>` or heading, the text inside must have sufficient contrast against that `blockColor`, not just the body. | ||
| - Never use `textColor="#ffffff"` on a block with `blockColor="#ffffff"` or a light `bodyColor`. | ||
|
|
||
| **Buttons:** | ||
| - `bgColor` and `textColor` on `<Button>` must contrast. Dark background → light text. Light background → dark text. | ||
| - If no explicit `textColor` is set on a `<Button>`, assume the document's `textBaseColor` will be used — ensure that still contrasts against the button `bgColor`. | ||
|
|
||
| **CodeBlock:** | ||
| - `<CodeBlock>` has its own `blockColor`. If you set a custom `blockColor` on a `<CodeBlock>`, also ensure the surrounding `bodyColor` and the code text color are visually distinct from that block. A good default is a slightly darker or muted tint of the body color (e.g. `#f1f5f9` on a white body). | ||
| - If you change `<CodeBlock blockColor="…">` to a dark color, you must also visually account for the code text — note that there is no explicit text color attribute on `<CodeBlock>`, so use `blockColor` values that contrast with the inherited text color. | ||
|
|
||
| **Icons:** | ||
| - `<Icons color="…">` sets the icon color. If the `<Icons>` block sits on a `bodyColor` background, the icon color must contrast against the body. White icons on a white body are invisible. | ||
| - If you set `blockColor` on the `<Icons>` element, icon color must contrast against that, not the body. | ||
|
|
||
| --- | ||
|
|
||
| ## Add Vertical Spacing Around Elements | ||
|
|
||
| Use `paddingTop` and `paddingBottom` on block elements to add breathing room. Emails without spacing feel dense and hard to scan. | ||
|
|
||
| Default approach: | ||
| - Headings (`<H1>`, `<H2>`, `<H3>`): add `paddingTop="24"` or `paddingTop="32"` unless they are the first element. | ||
| - `<Paragraph>` after a heading: `paddingBottom="8"` to `"16"` is typical. | ||
| - `<Button>`: add `paddingTop="24"` and `paddingBottom="24"` to give CTAs room. | ||
| - `<Divider>`: typically fine without explicit padding, but add `paddingTop="16" paddingBottom="16"` if elements feel crowded. | ||
| - `<Image />`: `paddingBottom="16"` unless immediately followed by a caption paragraph. | ||
|
|
||
| Use `bodyYPadding` on `<Style />` for global top/bottom padding inside the body — `"16"` to `"32"` is a sensible default. | ||
|
|
||
| ```xml | ||
| <!-- Good — elements breathe --> | ||
| <Style bodyColor="#ffffff" backgroundColor="#f1f5f9" bodyYPadding="24" /> | ||
| <H1 paddingTop="8" paddingBottom="4">Welcome aboard</H1> | ||
| <Paragraph paddingBottom="16">Here is what happens next.</Paragraph> | ||
| <Button href="https://loops.so" bgColor="#0f172a" textColor="#ffffff" align="center" paddingTop="8" paddingBottom="24">Get started</Button> | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Columns Cannot Be Rounded | ||
|
|
||
| `<Columns>` does not support border-radius. Do **not** apply `blockBorderRadius` to `<Columns>` or to block elements inside `<ColumnItem>` with the intention of rounding the column itself. | ||
|
|
||
| Why: columns render as adjacent table cells. Two rounded blocks placed side by side produce awkward mismatched corners that look broken — each block has its own rounded corner butting up against the other. | ||
|
|
||
| Avoid this pattern: | ||
|
|
||
| ```xml | ||
| <!-- Bad — rounded blocks in columns look broken --> | ||
| <Columns gap="0" widths="50,50"> | ||
| <ColumnItem> | ||
| <Paragraph blockColor="#e2e8f0" blockBorderRadius="12">Left</Paragraph> | ||
| </ColumnItem> | ||
| <ColumnItem> | ||
| <Paragraph blockColor="#e2e8f0" blockBorderRadius="12">Right</Paragraph> | ||
| </ColumnItem> | ||
| </Columns> | ||
| ``` | ||
|
|
||
| Rounding is fine on standalone blocks (outside `<Columns>`), on `<Button>`, and on `<Image />`. | ||
|
|
||
| --- | ||
|
|
||
| ## CodeBlock Color Pairing | ||
|
|
||
| When you set a custom `blockColor` on a `<CodeBlock>`, visually pair it with the surrounding body: | ||
|
|
||
| - Light body (`bodyColor="#ffffff"`): use a subtle tinted block, e.g. `blockColor="#f8fafc"` or `blockColor="#f1f5f9"`. This creates separation without jarring contrast. | ||
| - Dark body (`bodyColor="#0f172a"`): use a slightly lighter dark, e.g. `blockColor="#1e293b"`. | ||
| - Avoid colorful block colors on `<CodeBlock>` — code should read as technical/neutral. | ||
|
|
||
| --- | ||
|
|
||
| ## Visual Hierarchy Summary | ||
|
|
||
| - One `<H1>` per document (unless the content genuinely has multiple top-level sections). | ||
| - Follow heading levels in order: `<H1>` → `<H2>` → `<H3>`. Don't skip levels for styling reasons — adjust `fontSize` instead. | ||
| - CTAs (`<Button>`) should stand out: high contrast, enough padding, aligned centrally for most transactional emails. | ||
| - Use `<Divider />` sparingly to separate distinct sections, not between every element. | ||
| - Keep icon rows (`<Icons>`) near the footer, typically the last or second-to-last block. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.