mosaic-headless 1.21.1 → 1.21.2
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.
- package/SKILL.md +7 -1
- package/assets/templates/platforms/claude-ai.json +1 -1
- package/assets/templates/platforms/claude-code.json +1 -1
- package/assets/templates/platforms/codex-cli.json +1 -1
- package/assets/templates/platforms/copilot.json +1 -1
- package/assets/templates/platforms/gemini-cli.json +1 -1
- package/data/style-properties.csv +11 -11
- package/package.json +1 -1
- package/references/dialog-and-triggers.md +27 -0
- package/references/styling.md +8 -3
- package/tools/extract_style_properties.py +42 -4
package/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: |
|
|
|
4
4
|
Build and modify Mosaic Pro (Nextend) sites by writing the underlying data model directly - no visual editor, no DOM. Query the real surface with `mo.py`, which joins every source table to the live sweeps so a lookup leads with the measured verdict rather than the declaration (126 node types, 191 properties, 98 style properties with 20 structured value shapes pinned down, 53 style states, 156 variants, 74 dynamic variables, 15 interaction triggers, 115 REST routes, 23 tables) instead of guessing, with every node type placed on a live site one at a time and asserted against the delivered HTML, the design-token and element-class layers verified against compiled CSS, the @VAR() dynamic language verified against rendered output, nine designed pages built through the tables themselves, and the delivered pages re-read in Chromium at three viewports so a rule that is present, correct and still wrong cannot pass. Drives Mosaic's own theme export/import and its plugin data upgrade from outside the editor and holds the copy against the source tree for tree. Measured on Mosaic Pro 1.0.9: the modal (`<dialog>`), OpenStreetMap, the exit-intent and scroll-depth triggers, run rules and the memory actions all built on a live page and read back, and the 1.0.7 -> 1.0.8 -> 1.0.9 migrations driven from outside wp-admin.
|
|
5
5
|
license: "MIT"
|
|
6
6
|
author: "moksa (https://moksaweb.com)"
|
|
7
|
-
version: "1.21.
|
|
7
|
+
version: "1.21.2"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Headless Mosaic
|
|
@@ -700,6 +700,12 @@ post — `build_all.py` resets first for that reason.
|
|
|
700
700
|
rows and `theme_zip_compare.php` reports a tree that does not match - delete
|
|
701
701
|
nodes with a missing parent REPEATEDLY until none are left, because each pass
|
|
702
702
|
orphans the next level down.
|
|
703
|
+
- **`width` / `height` and their min/max take the keyword `stretch` since 1.0.9**,
|
|
704
|
+
and Mosaic emits `-webkit-fill-available` before it so an older engine still gets
|
|
705
|
+
something. They are still token-referencable - `CSSSizePropertyFactory` extends
|
|
706
|
+
the collection-variable one, which is why `data/style-properties.csv` resolves a
|
|
707
|
+
factory's ancestry rather than testing its name. 39 properties take a token, not
|
|
708
|
+
the 34 counted before that fix.
|
|
703
709
|
- **A width copied out of Elementor needs `maxWidth: "100%"` beside it.**
|
|
704
710
|
Elementor caps every widget with `max-width:100%`, so a px width there is a
|
|
705
711
|
desktop intent its own CSS already constrains; carried across bare it keeps the
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"description": "Build and modify Mosaic Pro (Nextend) sites by writing the underlying data model directly - no visual editor, no DOM. Query the real surface (122 node types, 181 node properties, 98 style properties, 53 style states, 151 element classes, 74 dynamic variables, 114 REST routes, 23 tables) instead of guessing, with every node type placed on a live site one at a time and asserted against the delivered HTML, every style and node property swept against the compiled CSS and markup, and 569 responsive declarations checked against the stylesheet the site actually served.",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"author": "moksa (https://moksaweb.com)",
|
|
23
|
-
"version": "1.21.
|
|
23
|
+
"version": "1.21.2"
|
|
24
24
|
},
|
|
25
25
|
"loaderBehaviour": "Upload via Settings -> Skills -> Upload. Claude.ai parses SKILL.md frontmatter and surfaces the skill in your library. The extraction tool (extract-block-schema.php) needs a live WP-CLI connection and won't run in the sandbox; use it from a local terminal against your own site instead.",
|
|
26
26
|
"uploadSteps": [
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"description": "Build and modify Mosaic Pro (Nextend) sites by writing the underlying data model directly - no visual editor, no DOM. Query the real surface (122 node types, 181 node properties, 98 style properties, 53 style states, 151 element classes, 74 dynamic variables, 114 REST routes, 23 tables) instead of guessing, with every node type placed on a live site one at a time and asserted against the delivered HTML, every style and node property swept against the compiled CSS and markup, and 569 responsive declarations checked against the stylesheet the site actually served.",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"author": "moksa (https://moksaweb.com)",
|
|
23
|
-
"version": "1.21.
|
|
23
|
+
"version": "1.21.2"
|
|
24
24
|
},
|
|
25
25
|
"loaderBehaviour": "Auto-loads on session start when SKILL.md frontmatter parses successfully.",
|
|
26
26
|
"verified": true,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"description": "Build and modify Mosaic Pro (Nextend) sites by writing the underlying data model directly - no visual editor, no DOM. Query the real surface (122 node types, 181 node properties, 98 style properties, 53 style states, 151 element classes, 74 dynamic variables, 114 REST routes, 23 tables) instead of guessing, with every node type placed on a live site one at a time and asserted against the delivered HTML, every style and node property swept against the compiled CSS and markup, and 569 responsive declarations checked against the stylesheet the site actually served.",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"author": "moksa (https://moksaweb.com)",
|
|
23
|
-
"version": "1.21.
|
|
23
|
+
"version": "1.21.2"
|
|
24
24
|
},
|
|
25
25
|
"loaderBehaviour": "Confirmed (2026-07-11): Codex CLI natively supports the SKILL.md spec. Place SKILL.md under .codex/skills/<name>/ (project) or ~/.codex/skills/<name>/ (personal) and Codex loads the name+description at session start, then the full body on demand. A parallel, broader convention .agents/skills/ (searched from cwd up to repo root, then ~/.agents/skills/) also exists across multiple tools - if your Codex CLI version prioritizes that path instead, mirror the same SKILL.md there.",
|
|
26
26
|
"verified": true,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"description": "Build and modify Mosaic Pro (Nextend) sites by writing the underlying data model directly - no visual editor, no DOM. Query the real surface (122 node types, 181 node properties, 98 style properties, 53 style states, 151 element classes, 74 dynamic variables, 114 REST routes, 23 tables) instead of guessing, with every node type placed on a live site one at a time and asserted against the delivered HTML, every style and node property swept against the compiled CSS and markup, and 569 responsive declarations checked against the stylesheet the site actually served.",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"author": "moksa (https://moksaweb.com)",
|
|
23
|
-
"version": "1.21.
|
|
23
|
+
"version": "1.21.2"
|
|
24
24
|
},
|
|
25
25
|
"loaderBehaviour": "CHANGED as of 2026-07-11: GitHub Copilot added a proper '.github/skills/' Agent Skills directory (December 2025), alongside the older single-file .github/copilot-instructions.md convention. This config targets the new skills-directory form. If your Copilot version predates this (pre Dec 2025), use the instructions-append fallback instead (see fallback below).",
|
|
26
26
|
"fallback": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"description": "Build and modify Mosaic Pro (Nextend) sites by writing the underlying data model directly - no visual editor, no DOM. Query the real surface (122 node types, 181 node properties, 98 style properties, 53 style states, 151 element classes, 74 dynamic variables, 114 REST routes, 23 tables) instead of guessing, with every node type placed on a live site one at a time and asserted against the delivered HTML, every style and node property swept against the compiled CSS and markup, and 569 responsive declarations checked against the stylesheet the site actually served.",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"author": "moksa (https://moksaweb.com)",
|
|
23
|
-
"version": "1.21.
|
|
23
|
+
"version": "1.21.2"
|
|
24
24
|
},
|
|
25
25
|
"loaderBehaviour": "CHANGED as of 2026-07-11: Gemini CLI now natively supports the same SKILL.md standard as Claude Code and Codex CLI - the same directory-based skill works unmodified. Gemini CLI discovers skills in this precedence order: built-in, extension skills, ~/.gemini/skills/ (personal), .gemini/skills/ (project, shared via version control). At session start Gemini injects each discovered skill's name+description into the system prompt and calls activate_skill when a task matches.",
|
|
26
26
|
"verified": true,
|
|
@@ -38,12 +38,12 @@ wordSpacing,,CSSCollectionVariablePropertyFactory,,,yes
|
|
|
38
38
|
whiteSpace,,CSSPropertyFactory,,normal|pre-wrap|nowrap|pre,
|
|
39
39
|
textTransform,,CSSPropertyFactory,,none|lowercase|uppercase|capitalize,
|
|
40
40
|
textShadow,,CSSTextShadowStylePropertyFactory,,,
|
|
41
|
-
width,,CSSSizePropertyFactory,,,
|
|
42
|
-
minWidth,,CSSSizePropertyFactory,,,
|
|
43
|
-
maxWidth,,CSSSizePropertyFactory,,,
|
|
44
|
-
height,,CSSSizePropertyFactory,,,
|
|
45
|
-
minHeight,,CSSSizePropertyFactory,,,
|
|
46
|
-
maxHeight,,CSSSizePropertyFactory,,,
|
|
41
|
+
width,,CSSSizePropertyFactory,,,yes
|
|
42
|
+
minWidth,,CSSSizePropertyFactory,,,yes
|
|
43
|
+
maxWidth,,CSSSizePropertyFactory,,,yes
|
|
44
|
+
height,,CSSSizePropertyFactory,,,yes
|
|
45
|
+
minHeight,,CSSSizePropertyFactory,,,yes
|
|
46
|
+
maxHeight,,CSSSizePropertyFactory,,,yes
|
|
47
47
|
position,,CSSPropertyFactory,,static|relative|absolute|fixed|sticky,
|
|
48
48
|
zIndex,,CSSPropertyFactory,,,
|
|
49
49
|
top,,CSSCollectionVariablePropertyFactory,,,yes
|
|
@@ -61,19 +61,19 @@ paddingLeft,,CSSCollectionVariablePropertyFactory,,,yes
|
|
|
61
61
|
borderRadius,,CSSBorderRadiusPropertyFactory,,,
|
|
62
62
|
borderTopWidth,borderStyle,CSSGrouppedPropertyFactory,CSSCollectionVariableProperty,,yes
|
|
63
63
|
borderTopStyle,borderStyle,CSSGrouppedPropertyFactory,,,
|
|
64
|
-
borderTopColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,
|
|
64
|
+
borderTopColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,yes
|
|
65
65
|
borderRightWidth,borderStyle,CSSGrouppedPropertyFactory,CSSCollectionVariableProperty,,yes
|
|
66
66
|
borderRightStyle,borderStyle,CSSGrouppedPropertyFactory,,,
|
|
67
|
-
borderRightColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,
|
|
67
|
+
borderRightColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,yes
|
|
68
68
|
borderBottomWidth,borderStyle,CSSGrouppedPropertyFactory,CSSCollectionVariableProperty,,yes
|
|
69
69
|
borderBottomStyle,borderStyle,CSSGrouppedPropertyFactory,,,
|
|
70
|
-
borderBottomColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,
|
|
70
|
+
borderBottomColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,yes
|
|
71
71
|
borderLeftWidth,borderStyle,CSSGrouppedPropertyFactory,CSSCollectionVariableProperty,,yes
|
|
72
72
|
borderLeftStyle,borderStyle,CSSGrouppedPropertyFactory,,,
|
|
73
|
-
borderLeftColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,
|
|
73
|
+
borderLeftColor,borderStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,yes
|
|
74
74
|
outlineWidth,outlineStyle,CSSGrouppedPropertyFactory,CSSCollectionVariableProperty,,yes
|
|
75
75
|
outlineStyle,outlineStyle,CSSGrouppedPropertyFactory,,,
|
|
76
|
-
outlineColor,outlineStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,
|
|
76
|
+
outlineColor,outlineStyle,CSSGrouppedPropertyFactory,CSSColorProperty,,yes
|
|
77
77
|
outlineOffset,outlineStyle,CSSGrouppedPropertyFactory,CSSCollectionVariableProperty,,yes
|
|
78
78
|
boxShadow,,CSSBoxShadowStylePropertyFactory,,,
|
|
79
79
|
opacity,,CSSPropertyFactory,,,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mosaic-headless",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.2",
|
|
4
4
|
"description": "AI-agent skill: build Mosaic Pro (Nextend) WordPress sites by writing the underlying data model directly - 23 custom tables, no visual editor, no DOM. Every node type, style property and node property swept against a live install and asserted on the delivered HTML and compiled CSS. Installs into Claude Code, Cursor, Codex CLI, Gemini CLI, Copilot, Continue, Windsurf and Claude.ai.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wordpress",
|
|
@@ -198,6 +198,33 @@ anywhere. That is the skill's existing rule (`ValidatorDynamicCode` = bare strin
|
|
|
198
198
|
`ValidatorDynamicCodeObject` = `{"v": …}`) applying to a new element, and it is also
|
|
199
199
|
why those three can hold `@VAR('post/meta_lat')` and a custom field can drive the map.
|
|
200
200
|
|
|
201
|
+
## The rest of 1.0.9, briefly
|
|
202
|
+
|
|
203
|
+
Not everything in the release is a node you place. Four things that change how the
|
|
204
|
+
plugin behaves rather than what you can build:
|
|
205
|
+
|
|
206
|
+
- **`stretch` on the size properties.** `width`, `height` and their min/max moved to
|
|
207
|
+
`CSSSizePropertyFactory`, which accepts the keyword and emits
|
|
208
|
+
`width:-webkit-fill-available` **then** `width:stretch` — the modern value last so
|
|
209
|
+
a current engine lands on it and an older one keeps the alias. Measured on all
|
|
210
|
+
three of width / height / max-width; the author's casing is preserved as typed.
|
|
211
|
+
- **`ElementClassPruner`.** The generated `_<token>` class is now a placeholder while
|
|
212
|
+
the tree renders, and one pass over the finished HTML keeps it only where a
|
|
213
|
+
selector actually claimed it. The marker is random per render, so the pass can
|
|
214
|
+
never touch a class that arrived from post content or a shortcode. This is the
|
|
215
|
+
mechanism behind "an element whose styles compile to nothing has no generated
|
|
216
|
+
class" — it is a deliberate feature, not an accident.
|
|
217
|
+
- **Author and term page instances.** `PageInstance/PageTypes/Author` and `Term` let
|
|
218
|
+
the editor put a specific author or taxonomy term in front of an archive template;
|
|
219
|
+
a term has no assign of its own, because a term archive is only ever rendered by
|
|
220
|
+
its path.
|
|
221
|
+
- **`POST /template/createAutoTemplate`** (`resourceQuery`, `masterID`) creates the
|
|
222
|
+
automatic template a post type is missing — a template on the post type's PATH,
|
|
223
|
+
with nothing recorded against the resource that prompted it. Deliberately not the
|
|
224
|
+
assign endpoint: a post type whose resources cannot carry an assign still needs a
|
|
225
|
+
way to be designed, and conflating the two would make this look like an assign.
|
|
226
|
+
115 routes now, up from 114.
|
|
227
|
+
|
|
201
228
|
## What else moved in the delivered page
|
|
202
229
|
|
|
203
230
|
**The three per-breakpoint stylesheets became one.** Through 1.0.8 a page carried
|
package/references/styling.md
CHANGED
|
@@ -109,12 +109,13 @@ The `factory` column in `data/style-properties.csv` tells you the value shape:
|
|
|
109
109
|
| factory | write |
|
|
110
110
|
|---|---|
|
|
111
111
|
| `CSSPropertyFactory` (29) | a plain CSS value string — `"flex"`, `"center"`, `"700"` |
|
|
112
|
-
| `CSSCollectionVariablePropertyFactory` (
|
|
112
|
+
| `CSSCollectionVariablePropertyFactory` (20) | a length string, or a reference to a collection variable |
|
|
113
|
+
| `CSSSizePropertyFactory` (6) | `width`, `height` and their min/max. A collection-variable length like the row above - it is a subclass - plus the keyword **`stretch`**, which Mosaic emits as `-webkit-fill-available` FIRST and `stretch` second, so a current engine takes the standard value and an older one the alias. New in 1.0.9; measured. |
|
|
113
114
|
| `CSSColorPropertyFactory` (2) | `color`, `backgroundColor` — a colour string or variable reference |
|
|
114
115
|
| `CSSGrouppedPropertyFactory` (20) | one leg of `borderStyle`, `outlineStyle` or `gridChildPosition`; the data is keyed under the group |
|
|
115
116
|
| the other 21 | purpose-built shapes — shadow, transform, gradient, filter, mask. Read the factory named in the CSV. |
|
|
116
117
|
|
|
117
|
-
Plain strings were accepted verbatim for the properties probed above. The
|
|
118
|
+
Plain strings were accepted verbatim for the properties probed above. The 39
|
|
118
119
|
token-referencable properties are the interface to the collection/variable layer,
|
|
119
120
|
which is how a design system is meant to be expressed rather than hard-coding values
|
|
120
121
|
on every node.
|
|
@@ -127,7 +128,11 @@ lowest layer and it opts that node out of both reuse mechanisms:
|
|
|
127
128
|
1. **Variants** (`data/variants.csv`, 152 built in - Mosaic's element classes) carry
|
|
128
129
|
the shared look; a node points at one through `style.variant`.
|
|
129
130
|
2. **Collections → modes/skins → variables** are the token layer, the thing the
|
|
130
|
-
|
|
131
|
+
39 token-referencable properties reference. (34 until this was last counted:
|
|
132
|
+
`data/style-properties.csv` resolves a factory's ANCESTRY now rather than
|
|
133
|
+
testing its name, which 1.0.9 made necessary - `CSSSizePropertyFactory` extends
|
|
134
|
+
the collection-variable one - and which also recovered the five grouped colour
|
|
135
|
+
legs whose value class was always `CSSColorProperty`.)
|
|
131
136
|
|
|
132
137
|
Per-node `style` is for the exception, not the rule. Build a design by putting values
|
|
133
138
|
in the class and token layers and letting nodes inherit; reach for per-node style when
|
|
@@ -110,6 +110,44 @@ def style_enums(plugin_root):
|
|
|
110
110
|
return out
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
def factory_parents(plugin_root):
|
|
114
|
+
"""class -> its parent, for every property factory under Builder/Style.
|
|
115
|
+
|
|
116
|
+
Read because a factory's NAME stopped being enough in 1.0.9:
|
|
117
|
+
`CSSSizePropertyFactory extends CSSCollectionVariablePropertyFactory` and drives
|
|
118
|
+
width / height and their min and max, which still take a collection variable -
|
|
119
|
+
but a name test for "CollectionVariable" misses it and the table then says six
|
|
120
|
+
length properties cannot reference a design token, which is false.
|
|
121
|
+
"""
|
|
122
|
+
parents = {}
|
|
123
|
+
base = os.path.join(plugin_root, "Mosaic", "Builder", "Style")
|
|
124
|
+
for root, _dirs, files in os.walk(base):
|
|
125
|
+
for name in files:
|
|
126
|
+
if not name.endswith(".php"):
|
|
127
|
+
continue
|
|
128
|
+
with open(os.path.join(root, name), encoding="utf-8", errors="replace") as fh:
|
|
129
|
+
src = fh.read()
|
|
130
|
+
# `extends Foo` and `extends \Name\Space\Foo` both; only the last
|
|
131
|
+
# segment is kept, which is what the factory column shows.
|
|
132
|
+
bs = chr(92)
|
|
133
|
+
for m in re.finditer("class" + r"\s+(\w+)\s+extends\s+([" + bs * 2
|
|
134
|
+
+ r"\w]+)", src):
|
|
135
|
+
parents[m.group(1)] = m.group(2).split(bs)[-1]
|
|
136
|
+
return parents
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def is_tokenable(factory, value_class, parents):
|
|
140
|
+
"""Does this factory, or anything it inherits from, accept a collection variable?"""
|
|
141
|
+
for name in (factory, value_class):
|
|
142
|
+
seen = set()
|
|
143
|
+
while name and name not in seen:
|
|
144
|
+
if "CollectionVariable" in name or "Color" in name:
|
|
145
|
+
return True
|
|
146
|
+
seen.add(name)
|
|
147
|
+
name = parents.get(name)
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
|
|
113
151
|
def extract(plugin_root, out_dir):
|
|
114
152
|
enums = style_enums(plugin_root)
|
|
115
153
|
path = os.path.join(plugin_root, "Mosaic", "Builder", "Style", "SupportedStyleProperties.php")
|
|
@@ -118,6 +156,7 @@ def extract(plugin_root, out_dir):
|
|
|
118
156
|
with open(path, encoding="utf-8", errors="replace") as fh:
|
|
119
157
|
src = fh.read()
|
|
120
158
|
|
|
159
|
+
parents = factory_parents(plugin_root)
|
|
121
160
|
rows = []
|
|
122
161
|
for factory, first, member, value_class in RE_ADD.findall(src):
|
|
123
162
|
grouped = factory == "CSSGrouppedPropertyFactory"
|
|
@@ -128,10 +167,9 @@ def extract(plugin_root, out_dir):
|
|
|
128
167
|
"factory": factory,
|
|
129
168
|
"value_class": value_class.split("\\")[-1] if value_class else "",
|
|
130
169
|
"accepted_values": "|".join(enums.get(member if grouped else first, [])),
|
|
131
|
-
"tokenable": "yes" if (
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
) else "",
|
|
170
|
+
"tokenable": "yes" if is_tokenable(
|
|
171
|
+
factory, value_class.split("\\")[-1] if value_class else "",
|
|
172
|
+
parents) else "",
|
|
135
173
|
}
|
|
136
174
|
)
|
|
137
175
|
|