mosaic-headless 1.17.2 → 1.19.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.
Files changed (67) hide show
  1. package/README.ja.md +19 -10
  2. package/README.ko.md +19 -10
  3. package/README.md +18 -9
  4. package/README.zh-TW.md +17 -9
  5. package/SKILL.md +118 -40
  6. package/assets/templates/platforms/claude-ai.json +1 -1
  7. package/assets/templates/platforms/claude-code.json +1 -1
  8. package/assets/templates/platforms/codex-cli.json +1 -1
  9. package/assets/templates/platforms/copilot.json +1 -1
  10. package/assets/templates/platforms/gemini-cli.json +1 -1
  11. package/bin/check-release.mjs +2 -1
  12. package/data/accordion-verification.csv +1 -1
  13. package/data/browser-verification.csv +906 -906
  14. package/data/conversion-verification.csv +1 -1
  15. package/data/custom-fields-verification.csv +63 -0
  16. package/data/db-columns.csv +40 -36
  17. package/data/design-audit-acknowledged.csv +1 -0
  18. package/data/design-audit.csv +1 -1
  19. package/data/intro-verification.csv +7 -7
  20. package/data/loop-verification.csv +5 -5
  21. package/data/node-properties.csv +4 -3
  22. package/data/node-property-verification.csv +81 -80
  23. package/data/node-type-notes.csv +1 -1
  24. package/data/node-types.csv +9 -9
  25. package/data/node-verification.csv +100 -100
  26. package/data/rest-routes.csv +1 -1
  27. package/data/style-properties.csv +1 -1
  28. package/data/style-state-verification.csv +48 -48
  29. package/data/style-states.csv +32 -32
  30. package/data/style-verification.csv +1 -1
  31. package/data/theme-zip-verification.csv +10 -10
  32. package/data/variants.csv +153 -0
  33. package/evals/accordion-is-not-broken/graders/criteria.md +1 -1
  34. package/evals/grid-child-placement/graders/criteria.md +3 -3
  35. package/package.json +1 -1
  36. package/references/custom-fields.md +112 -0
  37. package/references/data-model.md +7 -6
  38. package/references/design-system.md +28 -16
  39. package/references/interactions.md +1 -1
  40. package/references/responsive.md +6 -6
  41. package/references/styling.md +23 -14
  42. package/references/upgrading.md +182 -0
  43. package/references/vs-elementor-gutenberg.md +1 -1
  44. package/references/write-protocol.md +1 -1
  45. package/sites/_moksa.py +67 -62
  46. package/sites/moksa.json +219 -219
  47. package/tools/bootstrap_probe_theme.php +1 -1
  48. package/tools/build_page.py +17 -11
  49. package/tools/build_site.py +1 -1
  50. package/tools/capture_live.py +42 -6
  51. package/tools/data_upgrade.py +74 -0
  52. package/tools/extract_node_types.py +1 -1
  53. package/tools/from_elementor.py +3 -3
  54. package/tools/list_fields.php +88 -0
  55. package/tools/mo.py +10 -9
  56. package/tools/probe.py +1 -1
  57. package/tools/sweep_components.py +1 -1
  58. package/tools/sweep_interactions.py +3 -3
  59. package/tools/sweep_node_properties.py +1 -1
  60. package/tools/sweep_node_types.py +20 -0
  61. package/tools/sweep_style_properties.py +6 -7
  62. package/tools/sweep_style_states.py +2 -2
  63. package/tools/theme_export.php +2 -2
  64. package/tools/theme_zip_compare.php +2 -2
  65. package/tools/verify_browser.py +6 -5
  66. package/tools/verify_rwd.py +17 -15
  67. package/data/element-classes.csv +0 -152
@@ -0,0 +1,182 @@
1
+ # Upgrading the plugin: what 1.0.7 → 1.0.8 did to the data, measured
2
+
3
+ A Mosaic plugin update is two events, not one. The files change when WordPress
4
+ installs the package; the DATA changes only when Mosaic's own upgrade flow has
5
+ walked its milestones, and until it has, the site is in a state nothing in this
6
+ skill can talk to: the editor namespace (`/wp-json/mosaic/v<version>`) is not
7
+ registered at all. Only `mosaic/<dataVersion>/<version>/upgrade` answers.
8
+
9
+ Everything below was done to the test site this skill was built on - a real
10
+ 1.0.7 theme with the worked example (1,286 nodes), the WooCommerce account page,
11
+ the nineteen Elementor conversions and every probe master on it - and then
12
+ every sweep was re-run against the result.
13
+
14
+ ## Driving the upgrade from outside wp-admin
15
+
16
+ ```
17
+ python tools/data_upgrade.py mk.json --status
18
+ editor running : - (data upgrade pending)
19
+ upgrade namespace : mosaic/1.0.8/1.0.8
20
+
21
+ python tools/data_upgrade.py mk.json
22
+ processing 4426b1d4, 6 milestones
23
+ clone ok (1 call, 4.0s)
24
+ backup ok (5 calls, 20.8s)
25
+ 1.0.8 ok (8 calls, 35.2s)
26
+ restore ok (1 call, 1.5s)
27
+ set-data-version ok (1 call, 1.3s)
28
+ replace-plugin ok (1 call, 1.8s)
29
+ done - https://<site> now serves v1.0.8; mk.json version set to 1.0.8
30
+ ```
31
+
32
+ Three things about that route worth knowing before you call it:
33
+
34
+ - **It is the same milestone protocol as the theme ZIP flow** (`theme_zip.py`):
35
+ POST once to Start, then POST `{processingID, milestoneID}` until `isCompleted`.
36
+ `data_upgrade.py` reuses `Flow` from `theme_zip.py` for exactly that reason.
37
+ - **It refuses to start without `siteID`** (`Missing siteID`), even on a single
38
+ site. `1` is the blog ID there; the tool sends it.
39
+ - **The upgrade namespace stays registered after the upgrade.** Its presence means
40
+ nothing. The signal that Mosaic is running again is the versioned
41
+ `mosaic/v<version>/pluggable/endpoint` namespace in the REST index - the editor
42
+ namespace itself is a regex (`mosaic/v(?P<mosaicVersion>...)`) and cannot be
43
+ read for a version.
44
+ - **`wp plugin install <zip> --force` may not replace the plugin.** WordPress
45
+ installed the 1.0.8 package beside 1.0.7 as `mosaic-next`, inactive, because the
46
+ slug it derived did not match. Deactivate, move the folders, activate: the
47
+ files were then 1.0.8 and the data still 1.0.7, which is the state the tool
48
+ above expects.
49
+
50
+ The plugin clones every table before touching it, works on the clones, and swaps
51
+ at the end (`MilestoneRestore`), so a tick that dies mid-way leaves the live
52
+ tables alone. Back up anyway: `wp db export --tables=<the 23 mosaic tables>`.
53
+
54
+ ## What the migration rewrote
55
+
56
+ Read off `MosaicUpgradeRunLayer/Upgrades/Upgrade-1.0.8.php` and confirmed on the
57
+ rows afterwards.
58
+
59
+ **Four tables renamed** (the clones are renamed, last batch of the file):
60
+
61
+ | 1.0.7 | 1.0.8 |
62
+ |---|---|
63
+ | `mosaic_element_classes` | `mosaic_variants` |
64
+ | `mosaic_sub_classes` | `mosaic_variant_sub_classes` |
65
+ | `mosaic_utility_classes` | `mosaic_universal_classes` |
66
+ | `mosaic_utility_sub_classes` | `mosaic_universal_sub_classes` |
67
+
68
+ Still 23 tables (22 in the schema plus `mosaic_locks`); 210 columns rather than
69
+ 206, because four tables gained an `emittedName` column - a write-only projection
70
+ of the class or custom-property name each row emits, with a per-theme UNIQUE
71
+ index. Two classes in one theme can no longer emit the same spelling. The column
72
+ is declared `CHARACTER SET ascii COLLATE ascii_bin` so the index fits a 4K
73
+ InnoDB page; the source comments explain why at length.
74
+
75
+ **The stored discriminators inside `data`** - the keys the identifier renames had
76
+ deliberately skipped so they could move once, with a migration:
77
+
78
+ | where | 1.0.7 | 1.0.8 |
79
+ |---|---|---|
80
+ | node `style` key | `elementClass` | `variant` |
81
+ | node `style` key | `utilityClasses` | `universalClasses` |
82
+ | node `style` key | `defaultClass` | `defaultStyleSelector` |
83
+ | `defaultStyleSelector.type` | `elementClass` / `subClass` / `utilityClass` / `utilitySubClass` / `custom` | `variant` / `variantSubClass` / `universalClass` / `universalSubClass` / `local` |
84
+ | interaction trigger / target `type` | the same four | the same four |
85
+ | `parentType` column on the two sub-class tables | `elementClass`, `subClass`, `utilityClass`, `utilitySubClass` | `variant`, `variantSubClass`, `universalClass`, `universalSubClass` |
86
+ | style-state property, nodes AND every class row | `customStyles` | `customDeclarations` |
87
+ | REST resource in checkout / commit envelopes | `elementClass`, `subClass`, `utilityClass`, `utilitySubClass`, `elementClassMeta` | `variant`, `variantSubClass`, `universalClass`, `universalSubClass`, `variantDefinition` |
88
+ | REST route | `/elementClassMeta` | `/variantCatalog` |
89
+
90
+ `ValidatorTargetDetails` accepts only the new spellings and DROPS what it does
91
+ not recognise, which is why the interaction rows are walked too: a class-level
92
+ interaction with a stale discriminator would quietly lose its trigger.
93
+
94
+ **Class names became a naming system** (`ClassNameHelper.php`; the source calls
95
+ it WYSIWYG class names). Every class, sub class and variant sub class had its
96
+ freeform name folded into a canonical segment: transliterate, lowercase, replace
97
+ anything outside `[a-z0-9_-]` with `-`, collapse runs, cap at 60 characters, fold
98
+ the size scale (`s`→`sm`, `m`→`md`, `l`→`lg`, `xxs`→`2xs` … `xxxxl`→`4xl`),
99
+ dedupe published siblings with `-2`, `-3`. A root segment may not start with a
100
+ digit or with the reserved `m-`. A name that sanitizes to nothing becomes
101
+ `class`. The hidden `cssClass` override is cleared, but an emittable value is
102
+ kept as `data.legacyClassName` so the class still emits it as an extra selector.
103
+
104
+ **The catalog grew by one.** Badge, which used to be a sub-class tree under the
105
+ Button variant, is its own variant (`1d964ef1-…`, `m-badge`); the legacy tree is
106
+ left in place because existing pages point at it. 152 entries in
107
+ `data/variants.csv`, 151 before.
108
+
109
+ ## What changed in the delivered page
110
+
111
+ This is the part no row tells you about, and the part that broke something.
112
+
113
+ ```
114
+ 1.0.7 <div id="x" class="M_EL4 M_EL_Div"> .M_EL4{...}
115
+ <div class="M_EL7 M_EL_Text M_EL_WYSIWYG">
116
+ h2,.M_EL_Text__Heading2{...}
117
+ <div class="M_EL_AccordionItem M_EL_AccordionItem--opened">
118
+
119
+ 1.0.8 <div id="x" class="m-div _e"> ._e{...}
120
+ <div class="m-text m-wysiwyg _h">
121
+ h2,.m-heading-2{...}
122
+ <div class="m-accordion-item m-accordion-item--opened">
123
+ ```
124
+
125
+ - The per-element class is `_` + a base-38 token (`ElementTokenHelper`:
126
+ alphabet `a-z0-9-_`, so `_a` … `_9`, `_-`, `__`, then `_ba`). Single-case on
127
+ purpose: a shortcode that echoes before the doctype drops the page into quirks
128
+ mode, where class matching is case-insensitive, and `a`/`A` would share one
129
+ local style block. It comes LAST in the class list now; it came first.
130
+ - The type class is `m-<type>` (`m-div`, `m-section`, `m-menu-link`, `m-code`),
131
+ and a variant that renders its name adds it (`m-heading-2`). 113 of the 152
132
+ catalog entries render one; the rest (Body, HTML, the Gutenberg mirrors, the
133
+ accordion content inner) are matched by selector only. `renders_class` in
134
+ `data/variants.csv`.
135
+ - State classes moved with the type classes: `m-accordion-item--opened`,
136
+ `m-dropdown--opened`, `m-navbar--opened`, `m-menu-link--current`,
137
+ `m-dropdown-toggle--current`, `m-tab--active`, `m-slider-arrow--hidden`.
138
+ `data/style-states.csv` carries the new selector templates.
139
+ - The `<mosaic-*>` custom elements, the `mosaicInteractions` payload, the
140
+ `wp-theme-mosaic-1-1-<themeID>` body class and `body{opacity:0}` are unchanged.
141
+
142
+ The worked example's loop window opens by toggling the accordion and styling
143
+ `#mk-plate-item.M_EL_AccordionItem--opened{position:fixed;inset:0;…}`. After the
144
+ upgrade the migration had rewritten every row it owns, the page served with HTTP
145
+ 200 at the same size, the tap did toggle `aria-expanded` - and the panel did not
146
+ enlarge, because the class the selector named no longer exists. Nothing in the
147
+ plugin reports that; `verify_loop.py` OPENS (186x161 → 1920x900) is what saw it.
148
+ The selector now reads `m-accordion-item--opened`, and the lesson is in
149
+ `SKILL.md`: any CSS that names an emitted class is coupled to the plugin version.
150
+
151
+ ## What did not change
152
+
153
+ Re-extracted from the 1.0.8 source and diffed against 1.0.7: 122 node types, the
154
+ same 122 placement rules, 10 default structures, 74 dynamic variables, 12
155
+ interaction triggers, 22 animatable properties, 207 pluggable IDs, 53 style
156
+ states (12 templates re-spelt for the new class names), 98 style properties with
157
+ one renamed. Node properties went from 181 to 182: `button` gained `inactive`
158
+ (integer, `ValidatorInteger|ValidatorIntegerAsString`) and its emitted attribute
159
+ list gained `type`. The REST surface is 114 routes either way, one swapped.
160
+ The seven failure modes measured before are all still there, and the eighth is
161
+ this file.
162
+
163
+ ## Re-verifying after an upgrade
164
+
165
+ The order that worked, and why each step is there:
166
+
167
+ 1. `data_upgrade.py --status` until the editor namespace is back; set `version`
168
+ in every config (the tool does it for the one it was given).
169
+ 2. Re-extract from the new source tree and diff `data/*.csv` - the source says
170
+ what was renamed before any sweep has to discover it.
171
+ 3. `capture_live.py` for the routes, the catalog and the columns.
172
+ 4. Rebuild the worked example (`build_site.py`) - the first real write through
173
+ the renamed vocabulary, and the page has to come out byte-for-byte the same
174
+ apart from the tokens. It did (235,105 bytes, 1,286 nodes).
175
+ 5. `verify_loop.py`, `probe_accordion.py`, `sweep_node_types.py`,
176
+ `sweep_style_states.py`, then the rwd and browser passes. The loop check is
177
+ first because it is the one that failed.
178
+ 6. The ZIP round trip last - and prune the theme first. 223 accumulated masters
179
+ (98,261 nodes, 25 of them bound) made the 1.0.8 import time out at nginx's
180
+ five-minute upstream limit during `createTemplates`; at 25 masters and 8,608
181
+ nodes it finished in under two minutes and `theme_zip_compare.php` passed
182
+ 22 of 22, the four renamed tables included.
@@ -53,7 +53,7 @@ page" usually means editing a template, and the blast radius is every post that
53
53
  template is assigned to. Check `mosaic_template_assigns` before you edit.
54
54
 
55
55
  **"Style the element."** Elementor puts controls on the widget. Mosaic puts styling
56
- in a **class system** (151 built-in element classes) layered over a **token system**
56
+ in a **class system** (152 built-in variants - element classes) layered over a **token system**
57
57
  (collections → modes/skins → variables). Writing styles onto individual nodes works
58
58
  and is almost always wrong; it opts that node out of both layers.
59
59
 
@@ -27,7 +27,7 @@ Both `checkout` and `check` take one required string parameter, `syncCheckEnvelo
27
27
  pairs:
28
28
 
29
29
  ```json
30
- {"node": [["<nodeID>", "<revision>"], ...], "elementClass": [[...]]}
30
+ {"node": [["<nodeID>", "<revision>"], ...], "variant": [[...]]}
31
31
  ```
32
32
 
33
33
  The `revision` is the value from the row's `revision` column when you read it. The