mosaic-headless 1.2.0
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/LICENSE +21 -0
- package/README.ja.md +94 -0
- package/README.md +133 -0
- package/README.zh-CN.md +87 -0
- package/README.zh-TW.md +87 -0
- package/SKILL.md +353 -0
- package/assets/templates/platforms/claude-ai.json +34 -0
- package/assets/templates/platforms/claude-code.json +28 -0
- package/assets/templates/platforms/codex-cli.json +33 -0
- package/assets/templates/platforms/continue.json +31 -0
- package/assets/templates/platforms/copilot.json +46 -0
- package/assets/templates/platforms/cursor.json +36 -0
- package/assets/templates/platforms/gemini-cli.json +33 -0
- package/assets/templates/platforms/windsurf.json +34 -0
- package/bin/check-release.mjs +143 -0
- package/bin/install.mjs +452 -0
- package/bin/sync-version.mjs +63 -0
- package/data/animatable-properties.csv +23 -0
- package/data/condition-comparators.csv +13 -0
- package/data/condition-subjects.csv +60 -0
- package/data/db-columns.csv +207 -0
- package/data/default-children.csv +11 -0
- package/data/dynamic-variables.csv +75 -0
- package/data/element-classes.csv +152 -0
- package/data/evaluator-functions.csv +20 -0
- package/data/interaction-types.csv +13 -0
- package/data/node-properties.csv +182 -0
- package/data/node-property-verification.csv +182 -0
- package/data/node-types.csv +123 -0
- package/data/node-verification.csv +123 -0
- package/data/placement-rules.csv +123 -0
- package/data/pluggables.csv +208 -0
- package/data/property-verification.csv +171 -0
- package/data/rest-routes.csv +115 -0
- package/data/rwd-verification.csv +570 -0
- package/data/style-properties.csv +99 -0
- package/data/style-states.csv +54 -0
- package/data/style-value-shapes.csv +23 -0
- package/data/style-verification.csv +99 -0
- package/package.json +59 -0
- package/references/data-model.md +95 -0
- package/references/design-system.md +118 -0
- package/references/dynamic-content.md +113 -0
- package/references/failure-modes.md +182 -0
- package/references/interactions.md +126 -0
- package/references/placement.md +117 -0
- package/references/responsive.md +174 -0
- package/references/styling.md +172 -0
- package/references/templates-and-conditions.md +122 -0
- package/references/vs-elementor-gutenberg.md +73 -0
- package/references/write-protocol.md +79 -0
- package/sites/_moksa.py +1165 -0
- package/sites/moksa.json +8685 -0
- package/tools/bootstrap_probe_theme.php +68 -0
- package/tools/build_all.py +55 -0
- package/tools/build_page.py +352 -0
- package/tools/build_report.py +221 -0
- package/tools/build_site.py +174 -0
- package/tools/capture_live.py +130 -0
- package/tools/check_placement_predicts.py +72 -0
- package/tools/copy_styles.py +204 -0
- package/tools/extract_default_children.py +94 -0
- package/tools/extract_dynamic_variables.py +104 -0
- package/tools/extract_interactions.py +98 -0
- package/tools/extract_node_types.py +165 -0
- package/tools/extract_placement.py +135 -0
- package/tools/extract_pluggables.py +90 -0
- package/tools/extract_style_properties.py +163 -0
- package/tools/mint_session.php +52 -0
- package/tools/probe.py +144 -0
- package/tools/sweep_node_properties.py +271 -0
- package/tools/sweep_node_types.py +318 -0
- package/tools/sweep_properties.py +215 -0
- package/tools/sweep_style_properties.py +254 -0
- package/tools/theme_export.php +91 -0
- package/tools/theme_import.php +113 -0
- package/tools/verify_rwd.py +278 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "mosaic-headless"
|
|
3
|
+
description: |
|
|
4
|
+
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 properties, 98 style properties with 20 structured value shapes pinned down, 53 style states, 151 element classes, 74 dynamic variables, 12 interaction triggers, 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, the design-token and element-class layers verified against compiled CSS, the @VAR() dynamic language verified against rendered output, and nine designed pages built through the tables themselves.
|
|
5
|
+
license: "MIT"
|
|
6
|
+
author: "moksa (https://moksaweb.com)"
|
|
7
|
+
version: "1.2.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Headless Mosaic
|
|
11
|
+
|
|
12
|
+
Build Mosaic pages by writing the data model directly. The visual builder is one
|
|
13
|
+
client of that model; it is not the format, and you do not need it.
|
|
14
|
+
|
|
15
|
+
**Scope: page and template construction on a Mosaic site.** Not WordPress site
|
|
16
|
+
health, not plugin audits. If the site is not running Mosaic, this skill does not
|
|
17
|
+
apply — `references/vs-elementor-gutenberg.md` says which skill does.
|
|
18
|
+
|
|
19
|
+
## The one rule that overrides everything
|
|
20
|
+
|
|
21
|
+
**Never write a node type, property name, enum value, style key or Free/Pro claim
|
|
22
|
+
from memory. Look it up in `data/`.**
|
|
23
|
+
|
|
24
|
+
Then check the page. Mosaic has four failure modes and **only one of them changes the
|
|
25
|
+
HTTP status code**:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
clean validator rejection HTTP 200 + an `exceptions` array in the body
|
|
29
|
+
PHP fatal during commit HTTP 500 (15 of 122 types do this from a plain div)
|
|
30
|
+
structurally invalid node HTTP 200, committed, row in the DB, and the whole
|
|
31
|
+
public page becomes a 54-byte error string
|
|
32
|
+
wrong value SHAPE HTTP 200, stored, and the CSS rule is simply absent -
|
|
33
|
+
or worse, compiles to `transform:none`
|
|
34
|
+
no template for the URL HTTP 406 with an EMPTY BODY for anyone not logged in
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**406 is Mosaic's "no template matched".** `FrontendRenderer` answers
|
|
38
|
+
`TemplateNotFoundException` with `status_header(406)` and prints the explanation
|
|
39
|
+
only for an admin, so a logged-out visitor gets a blank page and a status code
|
|
40
|
+
that looks like a server problem. Two things make it easy to hit:
|
|
41
|
+
|
|
42
|
+
- **There are TWO ways to bind a template, and `createManualTemplate` is only one
|
|
43
|
+
of them.** That endpoint takes `resourceQuery=post/<id>` and `post` is the only
|
|
44
|
+
resource type it registers (`setResourceType('post')`, three call sites), so
|
|
45
|
+
through it there is no catch-all. But `assign` and `path` are first-class columns
|
|
46
|
+
on `wp_mosaic_templates`, and a template row committed with `assign:"auto"` and
|
|
47
|
+
`path:"index.php"` binds to a template PATH instead of a post. Measured A/B on a
|
|
48
|
+
URL with no template of its own: 406 with no such row, handled with it, 406 again
|
|
49
|
+
after deleting it. `X-Mosaic-Paths` on any 406 names the paths Mosaic looked for,
|
|
50
|
+
and `index.php` is in every list.
|
|
51
|
+
|
|
52
|
+
**Two limits, both measured.** `adminTemplateEditorInstance` does not return auto
|
|
53
|
+
templates at all - it listed only the three manual ones - so the admin surface
|
|
54
|
+
hides them. And an auto template's document has a `node/template/<id>` key but no
|
|
55
|
+
`template-internal` root: `heal()` builds that skeleton only for templates made
|
|
56
|
+
through `createManualTemplate`, and committing one directly answers HTTP 500. So
|
|
57
|
+
the row removes the 406 and I could not then put content in it. Not deployed on
|
|
58
|
+
the demo site for that reason - a 200 with an empty body is worse signal than a
|
|
59
|
+
406.
|
|
60
|
+
|
|
61
|
+
For `/` specifically the WordPress-side fix is the sound one: point the front page
|
|
62
|
+
at a post that has a template (`show_on_front=page`, `page_on_front=<id>`).
|
|
63
|
+
- **Activating a theme is not the same as populating it.** A fresh theme has no
|
|
64
|
+
templates, so between `wp theme activate` and a successful build the whole site
|
|
65
|
+
is 406 - and if the build fails, it stays that way. Never activate a new theme
|
|
66
|
+
as a step that can be separated from the commit that fills it.
|
|
67
|
+
|
|
68
|
+
A successful commit is not evidence of a working page. Fetch the page and check its
|
|
69
|
+
size. `references/failure-modes.md` has all of them, measured.
|
|
70
|
+
|
|
71
|
+
## What was verified, and how
|
|
72
|
+
|
|
73
|
+
Everything ran against a live install: WordPress 7.1, WooCommerce 11.1,
|
|
74
|
+
Mosaic Pro 1.0.7, **unlicensed** — the licence gates the theme library and updates,
|
|
75
|
+
not the node factories, so the Pro types register and render regardless.
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
WRITE PATH verified end to end over REST
|
|
79
|
+
theme -> master -> healed node tree -> template -> nodes -> public HTML
|
|
80
|
+
|
|
81
|
+
NODE SWEEP 122 of 122 node types, ONE PER DOCUMENT, committed then rendered then
|
|
82
|
+
deleted, asserting each type's attrID against the delivered HTML:
|
|
83
|
+
RENDERED 70 id found; tag and classes recorded
|
|
84
|
+
COMMITTED 30 row exists, nothing reached the page
|
|
85
|
+
COMMIT_5xx 15 PHP fatal on commit
|
|
86
|
+
BROKE_PAGE 7 committed, then the whole page died
|
|
87
|
+
Free 74: 43/22/6/3. Pro 48: 27/8/9/4. data/node-verification.csv
|
|
88
|
+
|
|
89
|
+
STYLE the states[state][breakpoint][property] shape confirmed by writing it
|
|
90
|
+
and reading back the compiled CSS; 20 of 22 structured value shapes
|
|
91
|
+
pinned down the same way. data/style-value-shapes.csv
|
|
92
|
+
|
|
93
|
+
DESIGN SYS element classes and collection variables both verified against compiled
|
|
94
|
+
CSS: an elementClass on the Heading 2 meta emitted a site-wide
|
|
95
|
+
h2,.M_EL_Text__Heading2{...} rule, and a collection variable emitted
|
|
96
|
+
:root{--brand: rgb(9, 99, 199)} with background-color:var(--brand).
|
|
97
|
+
references/design-system.md
|
|
98
|
+
|
|
99
|
+
DYNAMIC the @VAR('namespace/name') language verified against rendered output -
|
|
100
|
+
@VAR('post/title') produced the real post title, @concat/@substr/
|
|
101
|
+
@fallback all compose over it. 74 variables in
|
|
102
|
+
data/dynamic-variables.csv. references/dynamic-content.md
|
|
103
|
+
|
|
104
|
+
PROPERTIES 170 probes over the declared property surface, each value asserted
|
|
105
|
+
against the delivered markup and the compiled CSS separately.
|
|
106
|
+
data/property-verification.csv
|
|
107
|
+
|
|
108
|
+
RWD 569 responsive declarations across two sites asserted against the
|
|
109
|
+
stylesheet the site actually served - each `_t`/`_m` property matched
|
|
110
|
+
to its element's generated class inside that breakpoint's own media
|
|
111
|
+
query. All verified; the checker is itself checked against a poisoned
|
|
112
|
+
spec so a pass means something. data/rwd-verification.csv
|
|
113
|
+
|
|
114
|
+
BUILD nine complete designed pages built through the tables alone and checked
|
|
115
|
+
in a real browser, hover states included - the ninth uses only design
|
|
116
|
+
tokens, element-class typography and dynamic content, no hard-coded
|
|
117
|
+
colour anywhere, plus a real studio homepage rebuilt from the
|
|
118
|
+
live moksaweb.com. sites/_moksa.py is the one that ships.
|
|
119
|
+
|
|
120
|
+
MEASURED 114 REST routes, 151 element classes, 59 condition subjects,
|
|
121
|
+
23 tables / 206 columns - read off the running site.
|
|
122
|
+
|
|
123
|
+
FROM SOURCE 122 node types, 181 properties (61 with enums), 207 pluggable IDs,
|
|
124
|
+
122 placement rules, 10 composite default structures, 98 style
|
|
125
|
+
properties, 53 style states.
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Coverage, stated as a fraction rather than as a headline.** The verification
|
|
129
|
+
counts above are real, but they are not the same as "the surface is verified", and
|
|
130
|
+
the difference is worth being exact about:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
node types 122 / 122 swept live, one per document
|
|
134
|
+
node properties 181 / 181 re-probed with a value shaped by each property's
|
|
135
|
+
own validator chain: 35 APPLIED, 42 NO_EFFECT,
|
|
136
|
+
2 EDITOR_ONLY, 55 NO_HOST (no rendering type
|
|
137
|
+
declares them), 47 SKIPPED
|
|
138
|
+
style properties 98 / 98 swept live; 58 COMPILED, 18 ABSENT, 1 NO_ELEMENT,
|
|
139
|
+
21 SKIPPED (no test value could be synthesised, and
|
|
140
|
+
SKIPPED is never counted as a pass)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**A same-value probe measures the probe, not the surface.** The first property run
|
|
144
|
+
sent the string `MPROP0000X` to all 181 properties regardless of what each wanted,
|
|
145
|
+
and reported 91 NO_EFFECT. The tell was that `tagName` was in that list while the
|
|
146
|
+
entire demo site is built on it. Re-probed with a value derived from the declared
|
|
147
|
+
validator chain - array for `ValidatorArray`, boolean for `ValidatorBoolean`, a legal
|
|
148
|
+
enum member for `ValidatorAcceptedValues` - six of those NO_EFFECTs turn out to work:
|
|
149
|
+
`tagName`, `target`, `rel`, `height`, `size`, `insertLocation`.
|
|
150
|
+
|
|
151
|
+
**Some properties are gated by a companion.** `target` and `rel` did nothing until
|
|
152
|
+
the node also carried a `url`: `button` and `menu-link` render a `<span>` without one
|
|
153
|
+
and an `<a href>` with it, so an anchor-only attribute has nothing to attach to. A
|
|
154
|
+
NO_EFFECT is only meaningful once the property has been given the context it needs.
|
|
155
|
+
|
|
156
|
+
Twelve remain NO_EFFECT with a correctly shaped value, `cssClasses` and `attributes`
|
|
157
|
+
among them - recorded as measured-inert-with-this-shape rather than as dead, because
|
|
158
|
+
a third shape may yet be the right one.
|
|
159
|
+
|
|
160
|
+
**A property that belongs to a `group` is inert when you set it on its own.** This is
|
|
161
|
+
the sweep's one big result and it is exact:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
ungrouped 78 properties 58 COMPILED 0 ABSENT (20 SKIPPED)
|
|
165
|
+
grouped 20 properties 0 COMPILED 18 ABSENT (1 NO_ELEMENT, 1 SKIPPED)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Zero exceptions in either direction. The 20 are the `borderStyle` per-side longhands
|
|
169
|
+
(12), `outlineStyle` (4) and `gridChildPosition` (4) — so `borderLeftWidth`,
|
|
170
|
+
`outlineColor` and `gridColumnStart` are all instances of one rule rather than three
|
|
171
|
+
oddities. Set the grouped shape instead (`border` takes `{width, style, color}`), or
|
|
172
|
+
use `customStyles`. `data/style-verification.csv` carries the group beside the result
|
|
173
|
+
so the pattern is in the data, not just in this paragraph.
|
|
174
|
+
|
|
175
|
+
**Known gaps, stated rather than papered over.**
|
|
176
|
+
|
|
177
|
+
- `backgroundStyle` is the one style property whose shape resisted every attempt — it
|
|
178
|
+
accepts what you send and emits `background-image:none`. Use `customStyles` for
|
|
179
|
+
gradients, as the glass and darkglow pages do.
|
|
180
|
+
- **`gridColumnStart` / `gridColumnEnd` / `gridRowStart` / `gridRowEnd` emit nothing.**
|
|
181
|
+
All four are real entries in `data/style-properties.csv`, under `gridChildPosition`.
|
|
182
|
+
Measured: 16 `gridColumnStart` declarations committed, zero occurrences of
|
|
183
|
+
`grid-column` in the delivered CSS. Change the template; you cannot place a child.
|
|
184
|
+
- **Interaction property binding is unsolved.** The trigger, action slot and keyframe
|
|
185
|
+
timing all reach the browser; `propertyMetas` and per-keyframe `properties` do not.
|
|
186
|
+
Animate with the CSS transition/state path, which is fully verified.
|
|
187
|
+
- Committing a **condition** has not been driven end to end. The grammar in
|
|
188
|
+
`references/templates-and-conditions.md` is read from source and from the live
|
|
189
|
+
metas; an element carrying one rendered as hidden, which is consistent with the
|
|
190
|
+
condition evaluating false but is not proof the shape was understood.
|
|
191
|
+
|
|
192
|
+
## Orient yourself in this order
|
|
193
|
+
|
|
194
|
+
1. `references/data-model.md` — where a page actually lives. Read this first even if
|
|
195
|
+
you know Elementor; the answer is not `postmeta` and not `post_content`.
|
|
196
|
+
2. `references/write-protocol.md` — the checkout/check/commit sequence and envelopes.
|
|
197
|
+
3. `references/failure-modes.md` — how Mosaic fails, measured. Read before writing.
|
|
198
|
+
4. `references/placement.md` — what may go inside what, and what that table cannot
|
|
199
|
+
tell you.
|
|
200
|
+
5. `references/styling.md` — how a style value becomes CSS, and the shapes that are
|
|
201
|
+
silently inert if you write a string.
|
|
202
|
+
6. `references/responsive.md` - the state/breakpoint/property axis, the two
|
|
203
|
+
breakpoint rows, and the override that can change a property but never remove
|
|
204
|
+
one. **Read before writing any `_t` or `_m` value.**
|
|
205
|
+
7. `references/design-system.md` — element classes and design tokens. **Read this
|
|
206
|
+
before styling anything beyond a one-off page**; per-node style is the wrong layer
|
|
207
|
+
for a real site.
|
|
208
|
+
8. `references/dynamic-content.md` — the `@VAR()` language. The syntax is not
|
|
209
|
+
guessable, and a wrong guess renders as literal text rather than an error.
|
|
210
|
+
9. `references/templates-and-conditions.md` — how Mosaic picks a template, and the
|
|
211
|
+
condition grammar shared by templates, elements, interactions and form actions.
|
|
212
|
+
10. `references/interactions.md` — the JavaScript animation system, and how far it is
|
|
213
|
+
verified.
|
|
214
|
+
11. `references/vs-elementor-gutenberg.md` — which builder habits transfer.
|
|
215
|
+
|
|
216
|
+
## The data files
|
|
217
|
+
|
|
218
|
+
| file | rows | source |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| `data/node-verification.csv` | 122 | **swept live** — outcome, rendered tag and classes, page bytes, failure detail |
|
|
221
|
+
| `data/node-types.csv` | 122 | source — slug, label, edition, aliases, data class |
|
|
222
|
+
| `data/node-properties.csv` | 181 | source — property, validator chain, **accepted enum values**, `supportsInherit` |
|
|
223
|
+
| `data/placement-rules.csv` | 122 | source — which children each type accepts |
|
|
224
|
+
| `data/default-children.csv` | 10 | source — what a composite type needs **inside** it |
|
|
225
|
+
| `data/style-properties.csv` | 98 | source — every settable CSS property and its value shape |
|
|
226
|
+
| `data/style-value-shapes.csv` | 22 | **probed live** — the exact JSON shape for each structured value, and what it compiled to |
|
|
227
|
+
| `data/style-states.csv` | 53 | source — state IDs with their exact CSS selector templates |
|
|
228
|
+
| `data/property-verification.csv` | 170 | **probed live** — per-property effect on markup vs CSS, with unprovable enums marked INCONCLUSIVE |
|
|
229
|
+
| `data/node-property-verification.csv` | 181 | **swept live** — each property probed with a value shaped by its own validator chain, on a type that declares it |
|
|
230
|
+
| `data/style-verification.csv` | 98 | **swept live** — every style property written to a page and checked against the compiled CSS, with its group beside the result |
|
|
231
|
+
| `data/rwd-verification.csv` | 569 | **checked live** - every `_t`/`_m` declaration vs the served stylesheet, with status per row |
|
|
232
|
+
| `data/element-classes.csv` | 151 | **live** — the built-in class metas; their IDs are what an `elementClass` record must use |
|
|
233
|
+
| `data/dynamic-variables.csv` | 74 | source — every `@VAR('ns/name')` expression, by namespace |
|
|
234
|
+
| `data/evaluator-functions.csv` | 19 | source — the `@` functions with their arity |
|
|
235
|
+
| `data/interaction-types.csv` | 12 | source — trigger types, `timed` vs `progress` |
|
|
236
|
+
| `data/animatable-properties.csv` | 22 | source — what a keyframe can drive (**not** the same set as the style properties) |
|
|
237
|
+
| `data/condition-subjects.csv` | 59 | **live** — condition subjects per context |
|
|
238
|
+
| `data/condition-comparators.csv` | 12 | **live** — comparators and their operator sets |
|
|
239
|
+
| `data/pluggables.csv` | 207 | source — every `setID()` by registry |
|
|
240
|
+
| `data/rest-routes.csv` | 114 | **live** — method, path, args |
|
|
241
|
+
| `data/db-columns.csv` | 206 | **live** — every column of all 23 tables |
|
|
242
|
+
|
|
243
|
+
## Building a page
|
|
244
|
+
|
|
245
|
+
`tools/build_page.py` consumes a declarative spec and commits it through the verified
|
|
246
|
+
write path, refusing anything the tables say is unsafe. `tools/build_site.py` does the
|
|
247
|
+
same for a whole site: one master carrying the header and footer, one template document
|
|
248
|
+
per page.
|
|
249
|
+
|
|
250
|
+
**`sites/_moksa.py` is the worked example** - a real studio homepage (hero, statistics,
|
|
251
|
+
services, a nine-item work list, products, testimonials, CTA, footer) generated as a
|
|
252
|
+
spec and committed entirely through the tables. Read it for the shape of a real build:
|
|
253
|
+
the `bp()` breakpoint helper, the `code` node that carries the keyframes, the glass
|
|
254
|
+
header, and `apply_type()`.
|
|
255
|
+
|
|
256
|
+
A spec can carry a `theme` block, which is how a real site should be styled — design
|
|
257
|
+
tokens and element-class typography rather than per-node values:
|
|
258
|
+
|
|
259
|
+
```jsonc
|
|
260
|
+
"theme": {
|
|
261
|
+
"variables": {"--brand": {"type": "color", "value": "rgb(13,108,102)"}},
|
|
262
|
+
"elementClasses": {"Heading 1": {"&": {"_": {"color": {"token": "--brand"}}}}}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
`{"token": "--brand"}` anywhere in a style resolves to the `{"var": "<uuid>"}`
|
|
267
|
+
reference the compiler wants.
|
|
268
|
+
|
|
269
|
+
**Two brands in one theme need namespaced tokens and no element classes at all.**
|
|
270
|
+
Collection variables and element classes are both theme-global: two specs that each
|
|
271
|
+
declare `--ink` produce one `:root` with duplicate declarations, and two specs that
|
|
272
|
+
each style `Heading 1` produce one set of rules. Whichever committed last wins, for
|
|
273
|
+
every page. `sites/_moksa.py` namespaces its tokens (`--mk-*`) and bakes the type
|
|
274
|
+
system onto the nodes with `apply_type()` instead of using element classes, which is
|
|
275
|
+
what lets it share an install with a completely different design.
|
|
276
|
+
|
|
277
|
+
Whole themes move between installs with `theme_export.php` / `theme_import.php`.
|
|
278
|
+
A theme is a themeID scattered across nineteen tables, and every one of them has a
|
|
279
|
+
COMPOSITE primary key of `(themeID, ID)` — so an import can keep every internal id
|
|
280
|
+
and rewrite nothing but the theme, which means no id remapping and nothing left
|
|
281
|
+
dangling. Round-tripped and verified: a full theme exported, re-imported as a copy,
|
|
282
|
+
and the copy served byte-identical pages.
|
|
283
|
+
|
|
284
|
+
`copy_styles.py` pushes one node's style onto others by attrID or prefix, optionally
|
|
285
|
+
only certain `state.breakpoint` slices, and shows the diff before writing.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
wp eval-file tools/bootstrap_probe_theme.php # licence-free scratch theme
|
|
289
|
+
python tools/build_all.py --config sweep.json # reset + build every design
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Rebuilding a single page without a reset leaves an orphan template bound to the same
|
|
293
|
+
post — `build_all.py` resets first for that reason.
|
|
294
|
+
|
|
295
|
+
## Facts worth knowing before you look anything up
|
|
296
|
+
|
|
297
|
+
- **The REST namespace contains the plugin version** (`/wp-json/mosaic/v1.0.7`). Read
|
|
298
|
+
it from `mosaicOptions.rest_api_url`, never hardcode.
|
|
299
|
+
- **`ordering` is a fractional-index string**, not a number.
|
|
300
|
+
- **The tree is a `parentID` column**, not nesting. There is no page-level JSON blob.
|
|
301
|
+
- **Everything is scoped to a `themeID`**, breakpoints included.
|
|
302
|
+
- **A post is a target, not a container.** Templates bind to posts through
|
|
303
|
+
`mosaic_template_assigns`; one template serves many posts.
|
|
304
|
+
- **Only `wp_mosaic_locks` existing** means a half-installed Mosaic. The other 22
|
|
305
|
+
tables appear when an admin loads `/wp-admin/admin.php?page=mosaic`.
|
|
306
|
+
- **Commit has side effects.** `heal()` runs inside it and creates breakpoints,
|
|
307
|
+
collections and child nodes you never sent. Take every revision in the response.
|
|
308
|
+
- **`modified_gmt` is server-assigned.**
|
|
309
|
+
- **Styling hangs on the generated `.M_EL<n>` class, not your `attrID`**, and that
|
|
310
|
+
number is not stable. The sibling `M_EL_<Type>` class is.
|
|
311
|
+
- **`body{opacity:0}`** — the theme reveals itself from JavaScript. Screenshot tooling
|
|
312
|
+
must let scripts run or it captures a blank page.
|
|
313
|
+
|
|
314
|
+
## Rendered-tag facts you would otherwise guess wrong
|
|
315
|
+
|
|
316
|
+
- **`button` renders as `<span>`**, not `<button>`. So do `menu-link` and `wysiwyg-link`.
|
|
317
|
+
- **`text` renders as `<div>` by default** — set `tagName` for `<h1>`, `<p>` and so on.
|
|
318
|
+
- **Eight types emit custom elements**: `<mosaic-dropdown>`, `<mosaic-navbar>`,
|
|
319
|
+
`<mosaic-tabs>`, `<mosaic-accordion>`, `<mosaic-vimeo>`, `<mosaic-youtube>` and
|
|
320
|
+
friends. A selector written against `div`/`nav` misses all of them.
|
|
321
|
+
- **`icon` renders inline `<svg>`.**
|
|
322
|
+
|
|
323
|
+
## Regenerating everything
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
python tools/extract_node_types.py <plugin-root> data/
|
|
327
|
+
python tools/extract_pluggables.py <plugin-root> data/
|
|
328
|
+
python tools/extract_placement.py <plugin-root> data/
|
|
329
|
+
python tools/extract_default_children.py <plugin-root> data/
|
|
330
|
+
python tools/extract_style_properties.py <plugin-root> data/
|
|
331
|
+
python tools/extract_interactions.py <plugin-root> data/
|
|
332
|
+
python tools/extract_dynamic_variables.py <plugin-root> data/
|
|
333
|
+
python tools/capture_live.py data/ # from data/raw/*.json
|
|
334
|
+
# (raw dumps are gitignored;
|
|
335
|
+
# re-capture from a live site)
|
|
336
|
+
|
|
337
|
+
# against a scratch site - DESTRUCTIVE, never point at production
|
|
338
|
+
python tools/sweep_node_types.py --config sweep.json --setup
|
|
339
|
+
python tools/sweep_node_types.py --config sweep.json --sweep --edition all
|
|
340
|
+
python tools/sweep_properties.py --config sweep.json
|
|
341
|
+
python tools/verify_rwd.py --config sweep.json --site sites/moksa.json --csv data/rwd-verification.csv
|
|
342
|
+
python tools/sweep_style_properties.py --config sweep.json --page moksa --csv data/style-verification.csv
|
|
343
|
+
python tools/sweep_node_properties.py --config sweep.json --page moksa --csv data/node-property-verification.csv
|
|
344
|
+
wp eval-file tools/theme_export.php active > theme.json
|
|
345
|
+
wp eval-file tools/theme_import.php theme.json "Copy" rebind activate
|
|
346
|
+
python tools/probe.py --config lab.json --cases cases.json # ad-hoc measurement
|
|
347
|
+
python tools/check_placement_predicts.py
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
`bootstrap_probe_theme.php` exists because Mosaic's own new-theme flow calls
|
|
351
|
+
`account.mosaicbuilder.com` and needs a licence. `EditorInstanceWithNewTheme->heal()`
|
|
352
|
+
does not — which is what made a licence-free fixture, and therefore this whole
|
|
353
|
+
verification, possible.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "claude-ai",
|
|
3
|
+
"displayName": "Claude.ai (web app)",
|
|
4
|
+
"installType": "zip-upload",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": null,
|
|
7
|
+
"globalRoot": null,
|
|
8
|
+
"skillPath": "mosaic-headless.zip",
|
|
9
|
+
"filename": "SKILL.md"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": true,
|
|
14
|
+
"tools": false,
|
|
15
|
+
"data": true,
|
|
16
|
+
"sites": true
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": {
|
|
19
|
+
"name": "mosaic-headless",
|
|
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
|
+
"license": "MIT",
|
|
22
|
+
"author": "moksa (https://moksaweb.com)",
|
|
23
|
+
"version": "1.2.0"
|
|
24
|
+
},
|
|
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
|
+
"uploadSteps": [
|
|
27
|
+
"1. Run: python tools/install-skill.py claude-ai --to ./build (creates elementor-headless.zip)",
|
|
28
|
+
"2. Open Claude.ai -> Settings -> Skills -> Upload",
|
|
29
|
+
"3. Pick the generated zip; the skill appears in your library",
|
|
30
|
+
"4. New chats auto-invoke when you ask to build/modify an Elementor page programmatically"
|
|
31
|
+
],
|
|
32
|
+
"verified": true,
|
|
33
|
+
"verifiedAsOf": "2026-09-06"
|
|
34
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "claude-code",
|
|
3
|
+
"displayName": "Claude Code",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": ".claude",
|
|
7
|
+
"globalRoot": "~/.claude",
|
|
8
|
+
"skillPath": "skills/mosaic-headless",
|
|
9
|
+
"filename": "SKILL.md"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": true,
|
|
14
|
+
"tools": true,
|
|
15
|
+
"data": true,
|
|
16
|
+
"sites": true
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": {
|
|
19
|
+
"name": "mosaic-headless",
|
|
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
|
+
"license": "MIT",
|
|
22
|
+
"author": "moksa (https://moksaweb.com)",
|
|
23
|
+
"version": "1.2.0"
|
|
24
|
+
},
|
|
25
|
+
"loaderBehaviour": "Auto-loads on session start when SKILL.md frontmatter parses successfully.",
|
|
26
|
+
"verified": true,
|
|
27
|
+
"verifiedAsOf": "2026-09-06"
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "codex-cli",
|
|
3
|
+
"displayName": "OpenAI Codex CLI",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": ".codex",
|
|
7
|
+
"globalRoot": "~/.codex",
|
|
8
|
+
"skillPath": "skills/mosaic-headless",
|
|
9
|
+
"filename": "SKILL.md"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": true,
|
|
14
|
+
"tools": true,
|
|
15
|
+
"data": true,
|
|
16
|
+
"sites": true
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": {
|
|
19
|
+
"name": "mosaic-headless",
|
|
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
|
+
"license": "MIT",
|
|
22
|
+
"author": "moksa (https://moksaweb.com)",
|
|
23
|
+
"version": "1.2.0"
|
|
24
|
+
},
|
|
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
|
+
"verified": true,
|
|
27
|
+
"verifiedAsOf": "2026-09-06",
|
|
28
|
+
"verificationNote": "Upgraded from unverified: as of 2026-07-11 this is documented, native behaviour, not best-effort. Still confirm against your specific Codex CLI version since .agents/skills/ vs .codex/skills/ precedence can vary by build.",
|
|
29
|
+
"embedReferences": [
|
|
30
|
+
"data-model.md",
|
|
31
|
+
"failure-modes.md"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "continue",
|
|
3
|
+
"displayName": "Continue (continue.dev)",
|
|
4
|
+
"installType": "rule",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": ".continue",
|
|
7
|
+
"globalRoot": "~/.continue",
|
|
8
|
+
"skillPath": "rules",
|
|
9
|
+
"filename": "mosaic-headless.md"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": false,
|
|
14
|
+
"tools": false,
|
|
15
|
+
"data": false,
|
|
16
|
+
"sites": false
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": {
|
|
19
|
+
"name": "mosaic-headless",
|
|
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
|
+
"alwaysApply": false
|
|
22
|
+
},
|
|
23
|
+
"loaderBehaviour": "Continue reads .continue/rules/*.md as Rules. Set alwaysApply: true to attach to every chat, or leave false and rely on the description for relevance matching. Rule files load in lexicographic order if you split this into several numbered files. References must be embedded inline; the installer concatenates key reference files into the rule body.",
|
|
24
|
+
"embedReferences": [
|
|
25
|
+
"data-model.md",
|
|
26
|
+
"failure-modes.md",
|
|
27
|
+
"responsive.md"
|
|
28
|
+
],
|
|
29
|
+
"verified": true,
|
|
30
|
+
"verifiedAsOf": "2026-09-06"
|
|
31
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "copilot",
|
|
3
|
+
"displayName": "GitHub Copilot",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": ".github",
|
|
7
|
+
"globalRoot": null,
|
|
8
|
+
"skillPath": "skills/mosaic-headless",
|
|
9
|
+
"filename": "SKILL.md"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": true,
|
|
14
|
+
"tools": true,
|
|
15
|
+
"data": true,
|
|
16
|
+
"sites": true
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": {
|
|
19
|
+
"name": "mosaic-headless",
|
|
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
|
+
"license": "MIT",
|
|
22
|
+
"author": "moksa (https://moksaweb.com)",
|
|
23
|
+
"version": "1.2.0"
|
|
24
|
+
},
|
|
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
|
+
"fallback": {
|
|
27
|
+
"installType": "instructions-append",
|
|
28
|
+
"projectRoot": ".github",
|
|
29
|
+
"filename": "copilot-instructions.md",
|
|
30
|
+
"appendMarker": "<!-- BEGIN: elementor-headless -->",
|
|
31
|
+
"appendMarkerEnd": "<!-- END: elementor-headless -->",
|
|
32
|
+
"embedReferences": [
|
|
33
|
+
"data-model.md",
|
|
34
|
+
"control-types.md",
|
|
35
|
+
"responsive.md"
|
|
36
|
+
],
|
|
37
|
+
"note": "Use this if your Copilot version does not support .github/skills/ Agent Skills yet."
|
|
38
|
+
},
|
|
39
|
+
"verified": true,
|
|
40
|
+
"verifiedAsOf": "2026-09-06",
|
|
41
|
+
"verificationNote": "The exact frontmatter/loading contract for .github/skills/ SKILL.md was not independently confirmed byte-for-byte at write time - verify against current GitHub Copilot docs before relying on it for a production install.",
|
|
42
|
+
"embedReferences": [
|
|
43
|
+
"data-model.md",
|
|
44
|
+
"failure-modes.md"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "cursor",
|
|
3
|
+
"displayName": "Cursor",
|
|
4
|
+
"installType": "rule",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": ".cursor",
|
|
7
|
+
"globalRoot": "~/.cursor",
|
|
8
|
+
"skillPath": "rules",
|
|
9
|
+
"filename": "mosaic-headless.mdc"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": false,
|
|
14
|
+
"tools": false,
|
|
15
|
+
"data": false,
|
|
16
|
+
"sites": false
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": {
|
|
19
|
+
"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.",
|
|
20
|
+
"globs": [
|
|
21
|
+
"**/*.php",
|
|
22
|
+
"**/wp-content/**",
|
|
23
|
+
"**/*.json",
|
|
24
|
+
"**/*.py"
|
|
25
|
+
],
|
|
26
|
+
"alwaysApply": false
|
|
27
|
+
},
|
|
28
|
+
"loaderBehaviour": "Cursor reads .cursor/rules/*.mdc as Project Rules. Set alwaysApply: true to auto-attach to every chat, or leave false to attach when filename globs match. Cursor does NOT load referenced files automatically - embed key content inline; keep the rule under ~6KB. Subdirectories are supported (.cursor/rules/wp/x.mdc) if you want to split this up further.",
|
|
29
|
+
"embedReferences": [
|
|
30
|
+
"data-model.md",
|
|
31
|
+
"failure-modes.md",
|
|
32
|
+
"responsive.md"
|
|
33
|
+
],
|
|
34
|
+
"verified": true,
|
|
35
|
+
"verifiedAsOf": "2026-09-06"
|
|
36
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "gemini-cli",
|
|
3
|
+
"displayName": "Gemini CLI",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": ".gemini",
|
|
7
|
+
"globalRoot": "~/.gemini",
|
|
8
|
+
"skillPath": "skills/mosaic-headless",
|
|
9
|
+
"filename": "SKILL.md"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": true,
|
|
14
|
+
"tools": true,
|
|
15
|
+
"data": true,
|
|
16
|
+
"sites": true
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": {
|
|
19
|
+
"name": "mosaic-headless",
|
|
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
|
+
"license": "MIT",
|
|
22
|
+
"author": "moksa (https://moksaweb.com)",
|
|
23
|
+
"version": "1.2.0"
|
|
24
|
+
},
|
|
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
|
+
"verified": true,
|
|
27
|
+
"verifiedAsOf": "2026-09-06",
|
|
28
|
+
"verificationNote": "This is a DIFFERENT convention than the older .gemini/extensions/<name>/GEMINI.md extension-wrapper approach some skills still ship - that approach still works for bundling a skill inside a distributable extension, but is no longer the simplest or only path for a standalone skill install. Re-check before assuming either convention if this drifts again.",
|
|
29
|
+
"embedReferences": [
|
|
30
|
+
"data-model.md",
|
|
31
|
+
"failure-modes.md"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "windsurf",
|
|
3
|
+
"displayName": "Windsurf (now Devin Desktop)",
|
|
4
|
+
"installType": "rule",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"projectRoot": ".devin",
|
|
7
|
+
"globalRoot": null,
|
|
8
|
+
"skillPath": "rules",
|
|
9
|
+
"filename": "mosaic-headless.md"
|
|
10
|
+
},
|
|
11
|
+
"sections": {
|
|
12
|
+
"skill": true,
|
|
13
|
+
"references": false,
|
|
14
|
+
"tools": false,
|
|
15
|
+
"data": false,
|
|
16
|
+
"sites": false
|
|
17
|
+
},
|
|
18
|
+
"frontmatter": null,
|
|
19
|
+
"loaderBehaviour": "CHANGED as of 2026-07-11: Cognition rebranded Windsurf to 'Devin Desktop' on 2026-06-02 (windsurf.com now redirects to devin.ai). New installs should target .devin/rules/*.md as plain markdown (no special frontmatter - group related content with XML-style tags like <workflow>...</workflow>). The old .windsurf/rules/*.md path is kept working as a fallback for pre-rebrand setups. Character limits apply: keep each rule file under ~12,000 characters. References must be embedded inline since Windsurf/Devin does not load referenced files automatically.",
|
|
20
|
+
"fallback": {
|
|
21
|
+
"projectRoot": ".windsurf",
|
|
22
|
+
"skillPath": "rules",
|
|
23
|
+
"filename": "elementor-headless.md",
|
|
24
|
+
"note": "Use this path instead if your installation predates the Devin Desktop rebrand and .devin/rules/ is not recognised."
|
|
25
|
+
},
|
|
26
|
+
"embedReferences": [
|
|
27
|
+
"data-model.md",
|
|
28
|
+
"failure-modes.md",
|
|
29
|
+
"responsive.md"
|
|
30
|
+
],
|
|
31
|
+
"verified": true,
|
|
32
|
+
"verifiedAsOf": "2026-09-06",
|
|
33
|
+
"verificationNote": "Verify which product name/path applies to your install before running - this is the platform most likely to keep shifting given the recent rebrand."
|
|
34
|
+
}
|