.cursor/skills/layout-design/SKILL.md
Generate FileMaker layout objects, preview them in the webviewer, iterate with the developer, then produce output as either XML2 fmxmlsnippet (for paste into FM Layout Mode) or self-contained HTML (for the Web Viewer path). Use when the developer says "design layout", "create layout objects", "build layout", "add fields to layout", "preview layout", or provides a layout spec to implement.
npx skillsauth add petrowsky/agentic-fm layout-designInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate layout objects from a design brief or a specification produced by layout-spec. The workflow is preview-first: the agent builds an HTML mock styled with the solution's FM theme CSS, pushes it to the webviewer for the developer to see, iterates on feedback, then produces the final output in the developer's chosen format.
Read agent/config/automation.json and check project_tier (preferred) or default_tier:
Also read companion_url and webviewer_url from automation.json — these are needed for preview pushes and deployment.
Read agent/CONTEXT.json for:
current_layout — the target layout (name, ID, base TO)tables — fields with IDs, types, and TO referencesrelationships — related TOs for portalsscripts — scripts for button wiringvalue_lists — for dropdowns and radio buttonslayouts — for navigation button targetsIf CONTEXT.json is absent or scoped to the wrong layout, ask the developer to create the layout shell in FM first, then run Push Context on it. The agent cannot generate layout objects without knowing the target layout's TO and the field IDs available in that context.
Read the theme data from agent/context/{solution}/:
# Resolve solution name from CONTEXT.json
cat agent/context/*/theme-manifest.json 2>/dev/null
cat agent/context/*/theme.css 2>/dev/null
cat agent/context/*/theme-classes.json 2>/dev/null
theme.css — the FM theme's CSS rules, used for HTML preview stylingtheme-manifest.json — color palette and layout builder constants (default margins, field height, label width, row spacing, portal row height)theme-classes.json — named style classes available in the solutionIf no theme data exists, inform the developer and suggest extracting it:
No theme data found for this solution. Run
python3 agent/scripts/extract_theme.pyto extract the theme CSS, manifest, and style classes. This enables accurate layout previews and ensures generated objects use valid theme styles.
Proceed with reasonable defaults if the developer wants to continue without theme data.
If a specification from layout-spec was provided, use it directly. Otherwise, conduct a brief design conversation:
layout-spec skill (grouping, hierarchy, alignment)All FM layout objects use absolute pixel positioning via Bounds (top, left, bottom, right). When calculating positions:
Build an HTML document that visually represents the layout design. The preview uses the FM theme CSS for accurate styling.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Layout Preview: {Layout Name}</title>
<style>
/* Inline the theme.css content here */
{theme_css_content}
/* Layout preview scaffolding */
.layout-preview { position: relative; width: {layout_width}px; margin: 0 auto; }
.layout-part { position: relative; border-bottom: 1px dashed #ccc; }
.layout-part-label { position: absolute; right: 4px; top: 2px; font-size: 10px; color: #999; }
.layout-object { position: absolute; box-sizing: border-box; }
</style>
</head>
<body>
<div class="layout-preview">
<!-- One div per layout part, with child objects absolutely positioned -->
</div>
</body>
</html>
Map FM layout object types to HTML elements:
| FM Object | HTML Representation |
|-----------|-------------------|
| Edit Box | <input type="text"> with field name as placeholder |
| Text Label | <span> or <label> with the text content |
| Button | <button> with the label text |
| Button Bar | <div> container with child <button> elements |
| Portal | <table> with header row and sample data rows |
| Rectangle | <div> with border/background styling |
| Line | <hr> or <div> with border styling |
| Pop-up Menu | <select> with value list options |
| Checkbox Set | <div> with <input type="checkbox"> elements |
| Radio Button Set | <div> with <input type="radio"> elements |
| Tab Control | <div> with tab headers and content panels |
| Web Viewer | <div> with a "Web Viewer" placeholder label |
| Container | <div> with a container icon or placeholder |
Apply theme class names as CSS classes on each element so the theme CSS styles them accurately.
Send the preview HTML to the webviewer via the companion server:
curl -s -X POST -H "Content-Type: application/json" \
-d '{"type": "layout-preview", "content": "<html content>"}' \
{companion_url}/webviewer/push
If the companion server is not reachable, fall back to writing the preview HTML to agent/sandbox/{layout-name}-preview.html and instruct the developer to open it in a browser.
Present the preview to the developer:
The layout preview has been pushed to the webviewer. Review the design and let me know what to change — for example:
- "Move the portal lower"
- "Make the name field wider"
- "Use the strong field style for the total"
- "Add a status badge in the header"
- "Switch to a two-column layout for the address fields"
For each revision:
Continue until the developer approves the design.
Once the design is approved, ask the developer:
The design is approved. How would you like the output?
- FM Layout Objects — XML2 fmxmlsnippet for paste into Layout Mode (native FileMaker path)
- Web Viewer HTML — self-contained HTML/CSS/JS app for a Web Viewer object (web-first path)
Generate XML2-formatted layout objects. The developer must have already created the layout shell in FM.
Before generating XML2, read an existing layout from xml_parsed/layouts/ to understand the solution's XML2 structure:
ls agent/xml_parsed/layouts/{solution}/ 2>/dev/null | head -5
Read one layout file to use as a structural reference for object types, attribute patterns, and nesting.
<fmxmlsnippet type="LayoutObjectList"><LayoutObject> element with a type attribute<Bounds top="T" left="L" bottom="B" right="R"/><LocalCSS name="ClassName"/> — only use classes from theme-classes.json<FieldObj table="TOName" id="FieldID" name="FieldName"/> — resolve all IDs from CONTEXT.json<LayoutObject> elements for each column field<Script id="N" name="ScriptName"/> for the wired script and optional <Parameter> for the script parameter calculationAfter generating XML2:
Write to agent/sandbox/{layout-name}-objects.xml
Run the validator:
python3 agent/scripts/validate_snippet.py agent/sandbox/{layout-name}-objects.xml
Fix any validation errors
Deploy per the current tier:
Tier 1 — load to clipboard and present paste instructions:
python3 agent/scripts/clipboard.py write agent/sandbox/{layout-name}-objects.xml
The layout objects are on your clipboard. To install them:
- Open {Layout Name} in Layout Mode
- ⌘V — paste the objects onto the layout
- Adjust positions as needed — objects are placed at their designed coordinates
Tier 2/3 — deploy via agent/scripts/deploy.py if layout paste automation is supported.
Generate a self-contained HTML file with the theme CSS, JavaScript data binding, and FM bridge integration. This is the same output as the webviewer-build skill — delegate to that skill if the developer chooses this path:
Switching to the
webviewer-buildskill for the Web Viewer output path.
After deployment, provide guidance based on the output path:
Layout objects have been pasted. In Layout Mode:
- Verify field bindings are correct (right-click > Field/Control > inspect the field reference)
- Check that button scripts are wired correctly (right-click > Button Setup)
- Adjust any positions that need fine-tuning
- If conditional formatting is needed, apply it manually — conditional formatting rules cannot be set via clipboard paste
- Save the layout and switch to Browse Mode to test
The Web Viewer HTML has been generated. To use it:
- Add a Web Viewer object to your layout in Layout Mode
- Set its URL to the HTML file path or embed the HTML directly via a calculation
- Install the companion FM scripts (data loader and event handler)
- Test data flow in both directions
theme-classes.json — never invent class names. If no class fits, use the closest match and note the limitation.XML2 clipboard class is auto-detected by clipboard.py from <LayoutObject elements.xml_parsed/layouts/ before generating these object types.development
Generate a complete web application inside a FileMaker Web Viewer — self-contained HTML/CSS/JS styled with the FM theme, plus companion FM bridge scripts for bidirectional data flow. Use when the developer says "web viewer", "webviewer app", "HTML in FileMaker", "build web viewer", or when the layout-design skill delegates to the web-first output path. Recommended for modern, responsive UI, complex interactions (drag-and-drop, charts, rich text), or solutions considering future migration off FileMaker.
development
Trace references to a FileMaker object across the entire solution. Supports usage reports ("where is this field used?"), impact analysis ("what breaks if I rename this?"), and dead object scans ("show unused fields/scripts"). Use when the developer says "trace", "find references", "where is X used", "impact of renaming", "unused fields/scripts", "dead code", "what references X", or "is X used anywhere".
development
Analyze a FileMaker solution and produce a structured profile covering data model, business logic, UI layer, integrations, and health metrics. Uses on-disk pre-processing to handle solutions of any size without sending raw XML through the agent. Use when the developer says "analyze solution", "solution overview", "solution analysis", "solution profile", "solution spec", "what does this solution do", "solution summary", or wants a high-level understanding of an entire FileMaker solution.
development
Interactive setup wizard for agentic-fm. Detects what's already configured, walks the user through each remaining step, and verifies completion before proceeding. Use when the developer says "help me set up", "setup", "get started", "onboard", "first time setup", "install agentic-fm", "configure agentic-fm", or is clearly new to the project and needs guidance.