mosaic-headless 1.30.1 → 1.31.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/README.ja.md +4 -2
- package/README.ko.md +4 -2
- package/README.md +5 -3
- package/README.zh-TW.md +4 -2
- package/SKILL.md +80 -36
- 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/browser-verification/moksa.csv +12 -12
- package/data/component-wall-verification.csv +1 -1
- package/data/condition-comparators.csv +2 -2
- package/data/content-loop-verification.csv +4 -1
- package/data/data-class-hierarchy.csv +1 -0
- package/data/dialog-form-verification.csv +2 -2
- package/data/dialog-verification.csv +1 -1
- package/data/form-surface-verification.csv +3 -0
- package/data/interaction-types.csv +1 -0
- package/data/intro-verification.csv +16 -16
- package/data/mobile-audit.csv +22 -19
- package/data/navigation-verification.csv +16 -13
- package/data/node-properties.csv +8 -3
- package/data/node-types.csv +1 -0
- package/data/node-verification.csv +3 -0
- package/data/placement-rules.csv +1 -0
- package/data/pluggables.csv +16 -4
- package/data/popover-verification.csv +38 -0
- package/data/style-states.csv +1 -0
- package/data/token-verification.csv +2 -2
- package/package.json +2 -1
- package/references/dialog-and-triggers.md +199 -8
- package/references/dynamic-content.md +19 -0
- package/references/failure-modes.md +36 -4
- package/references/styling.md +9 -0
- package/references/upgrading.md +46 -1
- package/scripts/check-release.mjs +7 -6
- package/sites/_dialogs.py +18 -8
- package/sites/_moksa.py +69 -39
- package/sites/_popovers.py +570 -0
- package/tools/audit_mobile.py +1 -1
- package/tools/sweep_node_types.py +55 -6
- package/tools/verify_dialog.py +3 -2
- package/tools/verify_dialog_lab.py +11 -11
- package/tools/verify_intro.py +5 -3
- package/tools/verify_popovers.py +348 -0
package/README.ja.md
CHANGED
|
@@ -137,13 +137,13 @@ commit の成功はページが動く証拠ではないし、正しいスタイ
|
|
|
137
137
|
|
|
138
138
|
## 何を、どう検証したか
|
|
139
139
|
|
|
140
|
-
すべて実際のインストールに対して実行 — WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.
|
|
140
|
+
すべて実際のインストールに対して実行 — WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.10、
|
|
141
141
|
**ライセンスなし**:ライセンスが制限するのはテーマライブラリと更新であってノードファクトリ
|
|
142
142
|
ではないので、Pro の型も登録・描画される。
|
|
143
143
|
|
|
144
144
|
| 項目 | 結果 |
|
|
145
145
|
|---|---|
|
|
146
|
-
| **ノード型** |
|
|
146
|
+
| **ノード型** | 129 / 129 を 1 型 1 ドキュメントでスイープ、commit → 描画 → 断言 → 削除:77 RENDERED、25 COMMITTED、15 COMMIT_5xx、12 BROKE_PAGE。1.0.8 で再スイープ:以前は黙って commit されていた 5 型が、親なしではページを落とすようになった。描画されなかった行のうち 3 つは「必要な親なしで commit した」というスイープ手法の産物で、その旨が行の横にある |
|
|
147
147
|
| **スタイルプロパティ** | 98 / 98 を実ページに書き、コンパイル済み CSS と照合:58 COMPILED、18 ABSENT、21 SKIPPED |
|
|
148
148
|
| **ノードプロパティ** | 191 / 191 を各プロパティ自身のバリデータ連鎖から導いた値で再探査:35 APPLIED、43 NO_EFFECT、55 NO_HOST、47 SKIPPED |
|
|
149
149
|
| **レスポンシブ** | 2 サイト計 733 件の `_t`/`_m` 宣言を、サイトが実際に配信したスタイルシートに対して 1 件ずつ断言 — 全件検証済み |
|
|
@@ -160,6 +160,7 @@ commit の成功はページが動く証拠ではないし、正しいスタイ
|
|
|
160
160
|
| **スキル自身** | `claude plugin eval .` — ユーザーが実際に尋ねる 5 問を各 3 回、スキルあり/なしの 2 腕、1 回ごとに LLM 審査 3 名。**あり:5 問すべて 1.00。なし:5 問すべて 0.00。** ベースラインの最善の回答は回答拒否だった |
|
|
161
161
|
| **ライブ計測** | REST ルート 115、variant 156、条件サブジェクト 59、23 テーブル / 210 カラム |
|
|
162
162
|
| **1.0.9 の新機能** | modal(`<dialog>`)、OpenStreetMap、exit-intent と scroll-depth のトリガー、run rules、memory アクション、modal ショートハンド — すべて実ページに作り、ブラウザで実際に操作:19 / 19。「離脱時ポップアップを 1 セッション 1 回」が配線なしのオブジェクト 1 つで済む |
|
|
163
|
+
| **1.0.10 の新機能** | popover — Mosaic 初のページをブロックしないダイアログ — をラボページに 8 通り作り、Chromium で実操作:37 / 37。スクロールもクリックも妨げないページ読み込み時の通知、アンカー付きメニューとカード、画面 9 マス、keepInView の反転とそのスタイル状態、`afterClose` でつないだ 3 ステップのツアー。加えて modal の Popover API 移行:top layer、`requestClose()`、host の `display` で閉じなくなる問題の解消 |
|
|
163
164
|
| **slider** | ファクトリが要求する入れ子でブラウザ実操作、19 / 19:宣言どおりの間隔で自走、矢印・ドット・キーボードで駆動、`prefers-reduced-motion` では自ら停止。ドットは実はテンプレートで、スライド数だけ複製され id は全部同じ |
|
|
164
165
|
| **本物のサイト** | 変換済み 19 ページを 1 つのサイトに:実メニューとページごとのモーダル。ナビ 46 / 46、モーダル 19 / 19、トリガー/ルール/記憶/閉じ方の組み合わせは 6 種 |
|
|
165
166
|
| **カスタムフィールド** | ACF と Meta Box、1 ページに 40 フィールド、`@VAR` / `@LOOP` で配信 HTML から読み戻し:62 のうち 59 が解決、3 つの空は理由付き;複数値フィールドのループはフィールドの行数どおりに描画。`tools/list_fields.php` が Mosaic の実際の登録名を出す |
|
|
@@ -243,6 +244,7 @@ loop grid、フォーム、カウントダウン、サードパーティ addon
|
|
|
243
244
|
| `theme_zip.py` / `theme_zip_compare.php` / `theme_delete.php` | Mosaic 自身の ZIP 書き出し/読み込みをエディタの外から駆動、コピーを元とツリー単位で照合、ライブテーマを拒否する完全削除 |
|
|
244
245
|
| `list_fields.php` | ある投稿のカスタムフィールドが登録する `@VAR` / `@LOOP` 名をすべて、値付きで |
|
|
245
246
|
| `verify_dialog.py` | 1.0.9 の modal・トリガー・run rules・memory をブラウザで実操作 |
|
|
247
|
+
| `verify_popovers.py` | 1.0.10 の popover の配置・ブロック・closedby・反転・連鎖をブラウザで実操作 |
|
|
246
248
|
| `data_upgrade.py` | プラグイン更新後、Mosaic のデータ移行を自身の milestone ルートで実行 — 終わるまでエディタ API は存在しない |
|
|
247
249
|
| `sweep_*.py` / `probe_*.py` | 表を作った計測器そのもの |
|
|
248
250
|
| `bootstrap_probe_theme.php` / `mint_session.php` | ライセンス不要の実験用テーマと、WP-CLI から作る REST セッション |
|
package/README.ko.md
CHANGED
|
@@ -133,13 +133,13 @@ commit 성공은 페이지가 동작한다는 증거가 아니고, 올바른 스
|
|
|
133
133
|
|
|
134
134
|
## 무엇을, 어떻게 검증했나
|
|
135
135
|
|
|
136
|
-
전부 실제 설치에서 실행 — WordPress 7.1, WooCommerce 11.1, Mosaic Pro 1.0.
|
|
136
|
+
전부 실제 설치에서 실행 — WordPress 7.1, WooCommerce 11.1, Mosaic Pro 1.0.10, **라이선스 없음**:
|
|
137
137
|
라이선스가 막는 것은 테마 라이브러리와 업데이트지 노드 팩토리가 아니라서 Pro 타입도 등록되고
|
|
138
138
|
렌더링된다.
|
|
139
139
|
|
|
140
140
|
| 항목 | 결과 |
|
|
141
141
|
|---|---|
|
|
142
|
-
| **노드 타입** |
|
|
142
|
+
| **노드 타입** | 129 / 129를 문서당 하나씩 스윕, commit → 렌더 → 단언 → 삭제: 77 RENDERED, 25 COMMITTED, 15 COMMIT_5xx, 12 BROKE_PAGE. 1.0.8에서 재스윕: 전에는 조용히 commit되던 5개 타입이 부모 없이는 페이지를 죽인다. 렌더되지 않은 행 중 셋은 "필요한 부모 없이 commit"한 스윕 방식의 산물이며, 그 사실이 행 옆에 적혀 있다 |
|
|
143
143
|
| **스타일 프로퍼티** | 98 / 98을 실제 페이지에 쓰고 컴파일된 CSS와 대조: 58 COMPILED, 18 ABSENT, 21 SKIPPED |
|
|
144
144
|
| **노드 프로퍼티** | 191 / 191을 각 프로퍼티 자신의 검증기 체인에서 도출한 값으로 재탐사: 35 APPLIED, 43 NO_EFFECT, 55 NO_HOST, 47 SKIPPED |
|
|
145
145
|
| **반응형** | 두 사이트 합쳐 733개의 `_t`/`_m` 선언을, 사이트가 실제로 내보낸 스타일시트에 대해 하나씩 단언 — 전부 검증됨 |
|
|
@@ -156,6 +156,7 @@ commit 성공은 페이지가 동작한다는 증거가 아니고, 올바른 스
|
|
|
156
156
|
| **스킬 자체** | `claude plugin eval .` — 사용자가 실제로 묻는 5문항을 각 3회, 스킬 있음/없음 두 팔로, 매회 LLM 심사 3명. **있음: 5문항 모두 1.00. 없음: 5문항 모두 0.00.** 베이스라인의 최선은 답변 거부였다 |
|
|
157
157
|
| **라이브 측정** | REST 라우트 115, variant 156, 조건 subject 59, 23 테이블 / 210 컬럼 |
|
|
158
158
|
| **1.0.9 신기능** | modal(`<dialog>`), OpenStreetMap, exit-intent·scroll-depth 트리거, run rules, memory 액션, modal 숏핸드를 실제 페이지에 만들고 브라우저에서 직접 조작: 19/19. "이탈 의도 팝업, 세션당 한 번"이 배선 없이 객체 하나 |
|
|
159
|
+
| **1.0.10 신기능** | popover — Mosaic 최초의 페이지를 막지 않는 다이얼로그 — 를 실험 페이지에 8가지로 만들고 Chromium에서 직접 조작: 37 / 37. 스크롤도 클릭도 막지 않는 페이지 로드 알림, 앵커 메뉴와 카드, 화면 9칸, keepInView 반전과 그 스타일 상태, `afterClose`로 이은 3단계 투어. 그리고 modal의 Popover API 이전: top layer, `requestClose()`, host의 `display`가 더 이상 닫히지 않게 만들지 않음 |
|
|
159
160
|
| **slider** | 팩토리가 요구하는 중첩으로 브라우저에서 실제 조작, 19/19: 선언한 간격으로 자동 전진, 화살표·불릿·키보드로 구동, `prefers-reduced-motion`에서 스스로 멈춤. 불릿은 사실 템플릿이라 슬라이드 수만큼 복제되고 id가 전부 같다 |
|
|
160
161
|
| **진짜 사이트** | 변환된 19개 페이지를 하나의 사이트로: 실제 메뉴와 페이지별 모달. 내비 46/46, 모달 19/19, 트리거·규칙·기억·닫기 조합 6종 |
|
|
161
162
|
| **커스텀 필드** | ACF와 Meta Box, 한 페이지에 40개 필드, `@VAR` / `@LOOP`로 전달된 HTML에서 읽어냄: 62개 중 59개 해석, 빈 3개는 이유 있음; 다중값 필드 루프는 필드의 행 수 그대로 렌더링. `tools/list_fields.php`가 Mosaic이 실제 등록하는 이름을 출력 |
|
|
@@ -237,6 +238,7 @@ loop grid, 폼, 카운트다운, 서드파티 addon — 은 동적이라 될 노
|
|
|
237
238
|
| `theme_zip.py` / `theme_zip_compare.php` / `theme_delete.php` | Mosaic 자체 ZIP 내보내기/가져오기를 에디터 밖에서 구동, 사본을 원본과 트리 단위로 대조, 라이브 테마를 거부하는 깨끗한 삭제 |
|
|
238
239
|
| `list_fields.php` | 한 글의 커스텀 필드가 등록하는 모든 `@VAR` / `@LOOP` 이름을 값과 함께 |
|
|
239
240
|
| `verify_dialog.py` | 1.0.9의 modal·트리거·run rules·memory를 브라우저에서 실제 조작 |
|
|
241
|
+
| `verify_popovers.py` | 1.0.10 popover의 배치·차단·closedby·반전·연쇄를 브라우저에서 직접 조작 |
|
|
240
242
|
| `data_upgrade.py` | 플러그인 업데이트 후 Mosaic의 데이터 이관을 자체 milestone 라우트로 실행 — 끝나기 전까지 에디터 API는 존재하지 않는다 |
|
|
241
243
|
| `sweep_*.py` / `probe_*.py` | 표를 만든 계측기 그 자체 |
|
|
242
244
|
| `bootstrap_probe_theme.php` / `mint_session.php` | 라이선스 없는 실험용 테마와 WP-CLI에서 만드는 REST 세션 |
|
package/README.md
CHANGED
|
@@ -167,7 +167,7 @@ the HTTP status code:
|
|
|
167
167
|
|
|
168
168
|
```
|
|
169
169
|
clean validator rejection HTTP 200 + an `exceptions` array in the body
|
|
170
|
-
PHP fatal during commit HTTP 500 (15 of
|
|
170
|
+
PHP fatal during commit HTTP 500 (15 of 129 types do this from a plain div)
|
|
171
171
|
structurally invalid node HTTP 200, committed, row in the DB, and the whole
|
|
172
172
|
public page becomes a 54-byte error string
|
|
173
173
|
wrong value SHAPE HTTP 200, stored, and the CSS rule is simply absent
|
|
@@ -194,12 +194,12 @@ than any naive healthy-page floor.
|
|
|
194
194
|
## What was verified, and how
|
|
195
195
|
|
|
196
196
|
Everything ran against a live install — WordPress 7.1, WooCommerce 11.1, Mosaic Pro
|
|
197
|
-
1.0.
|
|
197
|
+
1.0.10, **unlicensed**: the licence gates the theme library and updates, not the node
|
|
198
198
|
factories, so Pro types register and render regardless.
|
|
199
199
|
|
|
200
200
|
| pass | result |
|
|
201
201
|
|---|---|
|
|
202
|
-
| **node types** |
|
|
202
|
+
| **node types** | 129 / 129 swept one per document, committed → rendered → asserted → deleted: 77 RENDERED, 25 COMMITTED, 15 COMMIT_5xx, 12 BROKE_PAGE. Re-swept on 1.0.8: five types that used to commit silently now kill the page unparented. The non-rendering rows that are artefacts of committing without the required parent say so beside the row |
|
|
203
203
|
| **style properties** | 98 / 98 written to a live page and checked against the compiled CSS: 58 COMPILED, 18 ABSENT, 21 SKIPPED |
|
|
204
204
|
| **node properties** | 191 / 191 re-probed with a value shaped by each property's own validator chain: 35 APPLIED, 43 NO_EFFECT, 55 NO_HOST, 47 SKIPPED |
|
|
205
205
|
| **responsive** | 733 `_t`/`_m` declarations across two sites asserted against the stylesheet the site actually served — all verified |
|
|
@@ -216,6 +216,7 @@ factories, so Pro types register and render regardless.
|
|
|
216
216
|
| **the skill itself** | `claude plugin eval .` — five cases a user would ask, three runs each, with and without the skill loaded, three LLM judges a run. **With: 1.00 on all five. Without: 0.00 on all five.** The baseline's best answer was to refuse |
|
|
217
217
|
| **measured live** | 115 REST routes, 156 variants, 59 condition subjects, 23 tables / 210 columns |
|
|
218
218
|
| **1.0.9 features** | the modal (`<dialog>`), OpenStreetMap, the exit-intent and scroll-depth triggers, run rules, memory actions and the modal shorthand, each built on a live page and exercised in a real browser: 19 of 19. An exit-intent popup that fires once a session is one object, no wiring |
|
|
219
|
+
| **1.0.10 features** | the popover - Mosaic's first non-blocking dialog - built eight ways on a lab page and driven in Chromium: 37 of 37. A page-load notice that leaves the page scrollable and clickable, anchored menus and cards, the nine screen cells, the keepInView flip and its style state, a three-step tour on `afterClose`. Plus the modal's move onto the Popover API: top layer, `requestClose()`, and `display` on its host no longer pinning it open |
|
|
219
220
|
| **slider** | the whole family nested as its factories require and driven in a browser, 19 of 19: advances on its own delay, arrows and bullets and the keyboard move it, holds still under `prefers-reduced-motion`. The bullet turns out to be a template repeated per slide - same id on every copy |
|
|
220
221
|
| **a real site** | the nineteen converted Elementor pages assembled into one site with a real menu and a modal per page: 46 of 46 navigation checks, 19 of 19 modals, six distinct trigger / run-rule / memory / dismissal configurations |
|
|
221
222
|
| **custom fields** | ACF and Meta Box, forty fields on a page, read back through `@VAR` / `@LOOP` off the delivered HTML: 59 of 62 resolve, 3 empties explained; loops over multi-value fields rendered exactly the field's rows. `tools/list_fields.php` prints the names Mosaic actually registers |
|
|
@@ -303,6 +304,7 @@ and heading level — and it earned its place at once: it caught the converter l
|
|
|
303
304
|
| `theme_zip.py` / `theme_zip_compare.php` / `theme_delete.php` | Mosaic's own ZIP export/import from outside the editor, the copy held against the source, and a clean delete that refuses the live theme |
|
|
304
305
|
| `list_fields.php` | every `@VAR` / `@LOOP` name a post's custom fields register, with values |
|
|
305
306
|
| `verify_dialog.py` | the 1.0.9 modal, triggers, run rules and memory, driven in a browser |
|
|
307
|
+
| `verify_popovers.py` | the 1.0.10 popover: placement, blocking, closedby, flip, chaining, driven in a browser |
|
|
306
308
|
| `verify_slider.py` / `verify_navigation.py` | does the slider actually move; is every menu item a real link and every page reachable |
|
|
307
309
|
| `data_upgrade.py` | after a plugin update, Mosaic's data migration over its own milestone route - the editor API is gone until it runs |
|
|
308
310
|
| `sweep_*.py` / `probe_*.py` | the instruments the tables were made with |
|
package/README.zh-TW.md
CHANGED
|
@@ -159,12 +159,12 @@ commit 成功不代表頁面能用,樣式表正確也不代表。這裡每個
|
|
|
159
159
|
|
|
160
160
|
## 驗證了什麼,怎麼驗的
|
|
161
161
|
|
|
162
|
-
全部在真實站台上跑——WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.
|
|
162
|
+
全部在真實站台上跑——WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.10,**未授權**:
|
|
163
163
|
授權鎖的是主題庫和更新,不是節點工廠,所以 Pro 型別照樣註冊、照樣渲染。
|
|
164
164
|
|
|
165
165
|
| 項目 | 結果 |
|
|
166
166
|
|---|---|
|
|
167
|
-
| **節點型別** |
|
|
167
|
+
| **節點型別** | 129 / 129 逐一放進獨立文件,寫入 → 渲染 → 斷言 → 刪除:77 RENDERED、25 COMMITTED、15 COMMIT_5xx、12 BROKE_PAGE。在 1.0.8 上重掃:五個以前默默寫入的型別,沒放對父節點現在會直接弄死頁面。未渲染的當中有三個是「沒給父層」的掃描方法產物,註記就在列旁 |
|
|
168
168
|
| **樣式屬性** | 98 / 98 寫進真實頁面、對照編譯出的 CSS:58 COMPILED、18 ABSENT、21 SKIPPED |
|
|
169
169
|
| **節點屬性** | 191 / 191 用各自驗證鏈推出的值重新探測:35 APPLIED、43 NO_EFFECT、55 NO_HOST、47 SKIPPED |
|
|
170
170
|
| **響應式** | 兩個站共 733 條 `_t`/`_m` 宣告,對照網站實際送出的樣式表逐條斷言——全數通過 |
|
|
@@ -181,6 +181,7 @@ commit 成功不代表頁面能用,樣式表正確也不代表。這裡每個
|
|
|
181
181
|
| **技能本身** | `claude plugin eval .`——五個使用者真的會問的問題,各跑三次,有載技能和沒載各一臂,每次三個 LLM 裁判。**有:五題全 1.00。沒有:五題全 0.00。** 基準線最好的回答是拒答 |
|
|
182
182
|
| **線上量測** | 115 條 REST 路由、156 個 variant、59 個條件主體、23 張表 / 210 個欄位 |
|
|
183
183
|
| **1.0.9 新功能** | modal(`<dialog>`)、OpenStreetMap、exit-intent 與 scroll-depth 觸發、run rules、memory action 與 modal shorthand,全部建在真實頁面上並用瀏覽器實際操作:19 之 19。「離開意圖彈窗、每個 session 只出現一次」只需要一個物件,不用接線 |
|
|
184
|
+
| **1.0.10 新功能** | popover——Mosaic 第一個不阻擋頁面的浮動層——在實驗頁上做了八種,用 Chromium 實際操作:37 / 37。頁面載入時出現的通知不擋捲動也不擋點擊、錨定選單與資訊卡、螢幕九宮格、keepInView 翻面與它的樣式狀態、用 `afterClose` 串起來的三步導覽。另外是 modal 改用 Popover API:進入 top layer、改用 `requestClose()`、host 上寫 `display` 不再讓它關不起來 |
|
|
184
185
|
| **slider** | 整組照工廠要求嵌套後在瀏覽器裡實際操作,19 之 19:會自己按宣告的間隔前進、箭頭與圓點與鍵盤都能驅動、`prefers-reduced-motion` 下會自己停。圓點其實是樣板,依 slide 數複製,每個複製品 id 相同 |
|
|
185
186
|
| **真正的網站** | 19 個轉換頁組成一個站:真實選單、每頁一個彈窗。導覽 46 之 46、彈窗 19 之 19,六種不同的觸發/規則/記憶/關閉設定 |
|
|
186
187
|
| **自訂欄位** | ACF 與 Meta Box,一頁四十個欄位,透過 `@VAR` / `@LOOP` 從送達的 HTML 讀回:62 個裡 59 個解析正確、3 個空值有解釋;多值欄位的迴圈剛好渲染出欄位的列數。`tools/list_fields.php` 列出 Mosaic 真正註冊的名字 |
|
|
@@ -258,6 +259,7 @@ button / html / icon-list / divider / image 佔了全部元素的 99.6%。長尾
|
|
|
258
259
|
| `theme_zip.py` / `theme_zip_compare.php` / `theme_delete.php` | 在編輯器外驅動 Mosaic 自己的 ZIP 匯出匯入、副本對來源逐樹比對、以及拒絕刪 live 主題的乾淨刪除 |
|
|
259
260
|
| `list_fields.php` | 一篇文章的自訂欄位註冊了哪些 `@VAR` / `@LOOP` 名字,連值一起列出 |
|
|
260
261
|
| `verify_dialog.py` | 在瀏覽器裡實際操作 1.0.9 的 modal、觸發、run rules 與 memory |
|
|
262
|
+
| `verify_popovers.py` | 在瀏覽器裡實際操作 1.0.10 的 popover:位置、是否阻擋、closedby、翻面、串接 |
|
|
261
263
|
| `verify_slider.py` / `verify_navigation.py` | slider 真的會動嗎;選單每一項是不是真連結、每頁是不是都到得了 |
|
|
262
264
|
| `data_upgrade.py` | 外掛更新後,走 Mosaic 自己的 milestone 路由跑資料遷移——沒跑完之前編輯器 API 是不存在的 |
|
|
263
265
|
| `sweep_*.py` / `probe_*.py` | 那些表格是用這些儀器量出來的 |
|
package/SKILL.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "mosaic-headless"
|
|
3
3
|
description: |
|
|
4
|
-
Build and modify Mosaic Pro (Nextend) sites by writing the
|
|
4
|
+
Build and modify Mosaic Pro (Nextend) WordPress sites by writing the data model directly - no visual editor, no DOM. Query the real surface with `mo.py` (129 node types, 196 node properties, 98 style properties, 54 style states, 156 variants, 74 dynamic variables, 16 interaction triggers, 115 REST routes) where every lookup leads with the measured verdict, not the declaration: each node type placed on a live site one at a time, each style and node property swept against compiled CSS and markup, the delivered pages re-read in Chromium at three viewports. Measured on Mosaic Pro 1.0.10: the popover (anchored or screen-placed, the flip state, afterClose-chained tours), the modal on the Popover API, OpenStreetMap, exit-intent and scroll-depth triggers, run rules and memory. Drives theme export/import and the 1.0.7 -> 1.0.10 data upgrades from outside wp-admin.
|
|
5
5
|
license: "MIT"
|
|
6
6
|
metadata:
|
|
7
7
|
author: "moksa (https://moksaweb.com)"
|
|
8
|
-
version: "1.
|
|
8
|
+
version: "1.31.0"
|
|
9
9
|
homepage: "https://github.com/Moksa1123/mosaic-headless"
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -58,14 +58,14 @@ python tools/mo.py skeleton # a minimal valid page spec
|
|
|
58
58
|
|
|
59
59
|
`--json` on any of them for machine-readable output. Every answer leads with the
|
|
60
60
|
measured verdict rather than the declaration, because on this platform the two
|
|
61
|
-
disagree for 52 of the 122 types.
|
|
61
|
+
disagree for 52 of the 122 types they were first counted on.
|
|
62
62
|
|
|
63
63
|
Then check the page. Mosaic has eight failure modes and **only three of them change the
|
|
64
64
|
HTTP status code**:
|
|
65
65
|
|
|
66
66
|
```
|
|
67
67
|
clean validator rejection HTTP 200 + an `exceptions` array in the body
|
|
68
|
-
PHP fatal during commit HTTP 500 (15 of
|
|
68
|
+
PHP fatal during commit HTTP 500 (15 of 129 types do this from a plain div)
|
|
69
69
|
structurally invalid node HTTP 200, committed, row in the DB, and the whole
|
|
70
70
|
public page becomes a 54-byte error string
|
|
71
71
|
wrong value SHAPE HTTP 200, stored, and the CSS rule is simply absent -
|
|
@@ -133,24 +133,28 @@ measured.
|
|
|
133
133
|
## What was verified, and how
|
|
134
134
|
|
|
135
135
|
Everything ran against a live install: WordPress 7.1, WooCommerce 11.1,
|
|
136
|
-
Mosaic Pro 1.0.
|
|
136
|
+
Mosaic Pro 1.0.10, **unlicensed** — the licence gates the theme library and updates,
|
|
137
137
|
not the node factories, so the Pro types register and render regardless. The
|
|
138
|
-
site was built on 1.0.7 and upgraded in place
|
|
139
|
-
(`tools/data_upgrade.py`) ran over the real theme, and
|
|
140
|
-
re-
|
|
138
|
+
site was built on 1.0.7 and upgraded in place three times: every data migration
|
|
139
|
+
(`tools/data_upgrade.py`) ran over the real theme, and the source tables were
|
|
140
|
+
re-extracted from 1.0.10 and every demo verifier re-run on the result, so the
|
|
141
|
+
tables describe 1.0.10 as delivered, not as declared. Where a row is still a 1.0.9
|
|
142
|
+
measurement - the full node sweep, the property sweeps - the section says so.
|
|
141
143
|
|
|
142
144
|
```
|
|
143
145
|
WRITE PATH verified end to end over REST
|
|
144
146
|
theme -> master -> healed node tree -> template -> nodes -> public HTML
|
|
145
147
|
|
|
146
|
-
NODE SWEEP
|
|
148
|
+
NODE SWEEP 129 of 129 node types, ONE PER DOCUMENT, committed then rendered then
|
|
147
149
|
deleted, asserting each type's attrID against the delivered HTML:
|
|
148
|
-
RENDERED
|
|
150
|
+
RENDERED 77 id found; tag and classes recorded
|
|
149
151
|
COMMITTED 25 row exists, nothing reached the page
|
|
150
152
|
COMMIT_5xx 15 PHP fatal on commit
|
|
151
153
|
BROKE_PAGE 12 committed, then the whole page died
|
|
152
154
|
data/node-verification.csv. 1.0.9's four new types - modal,
|
|
153
|
-
modal-window, modal-overlay, openstreetmap - all render
|
|
155
|
+
modal-window, modal-overlay, openstreetmap - all render, and so
|
|
156
|
+
does 1.0.10's one, popover (<div popover=manual>, swept on 1.0.10;
|
|
157
|
+
the other rows are the 1.0.9 sweep).
|
|
154
158
|
Re-swept on 1.0.8: five types that used to commit and render
|
|
155
159
|
nothing (accordion-title, loop-pagination and its two buttons,
|
|
156
160
|
multi-steps-form-step) now kill the page instead - the render
|
|
@@ -206,7 +210,23 @@ DIALOG 1.0.9's features built on a live page and read back out of the
|
|
|
206
210
|
runs once a session and again in a new one, which is the cap rule
|
|
207
211
|
holding. The OpenStreetMap element carries the coordinates only in
|
|
208
212
|
the {"v": ...} object form. data/dialog-verification.csv,
|
|
209
|
-
references/dialog-and-triggers.md
|
|
213
|
+
references/dialog-and-triggers.md. Re-run on 1.0.10, 19 of 19, with
|
|
214
|
+
one row changed: the open modal is now in the top layer (1.0.10
|
|
215
|
+
moved it onto the Popover API - `dialog.open` is always false, read
|
|
216
|
+
`:popover-open`; close from script with `mosaicDialog.requestClose()`)
|
|
217
|
+
|
|
218
|
+
POPOVER 1.0.10's non-blocking surface on a lab page, 37 of 37 in Chromium:
|
|
219
|
+
a page-load notice leaves the page scrollable and clickable;
|
|
220
|
+
closedby nothing / clickOutside / everything each honoured; an
|
|
221
|
+
unanchored menu on its trigger to the pixel, an anchored card on
|
|
222
|
+
the element it names, the nine screen cells where they say;
|
|
223
|
+
keepInView flips and ___popover--flipped styles the flipped one -
|
|
224
|
+
and without it the popover does not overflow but slides back over
|
|
225
|
+
its own trigger. A three-step tour taught the two rules that decide
|
|
226
|
+
how any sequence is built: a dialog opened from inside another is
|
|
227
|
+
its child and closes with it, and closing a popover suspends the
|
|
228
|
+
interactions inside it - so steps advance on afterClose, never on a
|
|
229
|
+
button that opens the next one. data/popover-verification.csv
|
|
210
230
|
|
|
211
231
|
FIELDS ACF 6.8 and Meta Box 5.15, forty fields registered in code on a page,
|
|
212
232
|
read back off the delivered HTML: 59 of 62 expressions resolve to the
|
|
@@ -383,9 +403,10 @@ UPGRADE 1.0.7 -> 1.0.8 driven over the plugin's own milestone route from
|
|
|
383
403
|
one selector on the worked example that named an emitted class
|
|
384
404
|
stopped matching until it was rewritten. references/upgrading.md
|
|
385
405
|
|
|
386
|
-
FROM SOURCE
|
|
387
|
-
|
|
388
|
-
properties,
|
|
406
|
+
FROM SOURCE 129 node types, 196 properties (68 with enums), 261 pluggable IDs,
|
|
407
|
+
129 placement rules, 25 composite default structures (10 declared,
|
|
408
|
+
15 healed in), 98 style properties, 54 style states, 16 interaction
|
|
409
|
+
triggers - re-extracted from the 1.0.10 tree.
|
|
389
410
|
```
|
|
390
411
|
|
|
391
412
|
**Coverage, stated as a fraction rather than as a headline.** The verification
|
|
@@ -393,11 +414,15 @@ counts above are real, but they are not the same as "the surface is verified", a
|
|
|
393
414
|
the difference is worth being exact about:
|
|
394
415
|
|
|
395
416
|
```
|
|
396
|
-
node types
|
|
397
|
-
node properties 191 /
|
|
417
|
+
node types 129 / 129 swept live, one per document
|
|
418
|
+
node properties 191 / 196 re-probed with a value shaped by each property's
|
|
398
419
|
own validator chain: 38 APPLIED, 45 NO_EFFECT,
|
|
399
420
|
2 EDITOR_ONLY, 55 NO_HOST (no rendering type
|
|
400
421
|
declares them), 2 INSTRUMENT, 45 SKIPPED
|
|
422
|
+
(the five missing are 1.0.10's popover -
|
|
423
|
+
role, ariaLive, accessibleLabel, closedby,
|
|
424
|
+
positioning - measured on the popover lab
|
|
425
|
+
instead: data/popover-verification.csv)
|
|
401
426
|
style properties 98 / 98 swept live; 58 COMPILED, 18 ABSENT, 1 NO_ELEMENT,
|
|
402
427
|
21 SKIPPED (no test value could be synthesised, and
|
|
403
428
|
SKIPPED is never counted as a pass)
|
|
@@ -498,8 +523,9 @@ so the pattern is in the data, not just in this paragraph.
|
|
|
498
523
|
13. `references/custom-fields.md` — ACF and Meta Box fields as `@VAR` / `@LOOP`:
|
|
499
524
|
the names, what each field type resolves to, and the loop element that walks
|
|
500
525
|
a multi-value field. Measured, 62 rows.
|
|
501
|
-
14. `references/dialog-and-triggers.md` — 1.0.
|
|
502
|
-
|
|
526
|
+
14. `references/dialog-and-triggers.md` — the modal (and what 1.0.10's Popover API
|
|
527
|
+
move changed), the 1.0.10 popover, OpenStreetMap, the exit-intent / scroll-depth
|
|
528
|
+
triggers, run rules, memory and the shorthand.
|
|
503
529
|
15. `references/upgrading.md` — what a plugin update does to the data and to the
|
|
504
530
|
delivered page, measured on 1.0.7 -> 1.0.8; how to drive the migration and what
|
|
505
531
|
to re-verify afterwards.
|
|
@@ -508,14 +534,14 @@ so the pattern is in the data, not just in this paragraph.
|
|
|
508
534
|
|
|
509
535
|
| file | rows | source |
|
|
510
536
|
|---|---|---|
|
|
511
|
-
| `data/node-verification.csv` |
|
|
512
|
-
| `data/node-types.csv` |
|
|
513
|
-
| `data/node-properties.csv` |
|
|
514
|
-
| `data/placement-rules.csv` |
|
|
515
|
-
| `data/default-children.csv` |
|
|
537
|
+
| `data/node-verification.csv` | 129 | **swept live** — outcome, rendered tag and classes, page bytes, failure detail |
|
|
538
|
+
| `data/node-types.csv` | 129 | source — slug, label, edition, aliases, data class |
|
|
539
|
+
| `data/node-properties.csv` | 196 | source — property, validator chain, **accepted enum values**, `supportsInherit` |
|
|
540
|
+
| `data/placement-rules.csv` | 129 | source — which children each type accepts |
|
|
541
|
+
| `data/default-children.csv` | 25 | source — what a composite type needs **inside** it |
|
|
516
542
|
| `data/style-properties.csv` | 98 | source — every settable CSS property and its value shape |
|
|
517
543
|
| `data/style-value-shapes.csv` | 22 | **probed live** — the exact JSON shape for each structured value, and what it compiled to |
|
|
518
|
-
| `data/style-states.csv` |
|
|
544
|
+
| `data/style-states.csv` | 54 | source — state IDs with their exact CSS selector templates |
|
|
519
545
|
| `data/property-verification.csv` | 170 | **probed live** — per-property effect on markup vs CSS, with unprovable enums marked INCONCLUSIVE |
|
|
520
546
|
| `data/node-property-verification.csv` | 191 | **swept live** — each property probed with a value shaped by its own validator chain, on a type that declares it |
|
|
521
547
|
| `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 |
|
|
@@ -523,7 +549,7 @@ so the pattern is in the data, not just in this paragraph.
|
|
|
523
549
|
| `data/browser-verification/` | 4132 | **computed in Chromium** - declared vs `getComputedStyle` at three viewports, `not-comparable` labelled per row. One CSV per page, named by its slug |
|
|
524
550
|
| `data/design-audit-acknowledged.csv` | 3 | reviewed findings that will not be fixed, each with a written reason. An acknowledgement without a reason is a suppression wearing a better name, and the release gate refuses one |
|
|
525
551
|
| `data/design-audit.csv` | 26 | **computed in Chromium** - contrast, font fallback, CJK tracking, overflow, measure. Empty means it ran and found nothing |
|
|
526
|
-
| `data/data-class-hierarchy.csv` |
|
|
552
|
+
| `data/data-class-hierarchy.csv` | 126 | source - every data class and its parent, so a type's inherited properties can be resolved |
|
|
527
553
|
| `data/style-state-verification.csv` | 52 | **swept live** - each state written on a host of its own type and matched against its promised selector |
|
|
528
554
|
| `data/component-verification.csv` | 8 | **driven live** - the component lifecycle, each step asserted against the row or the delivered HTML |
|
|
529
555
|
| `data/loop-verification.csv` | 28 | **measured live** - a perpetual animation: periodicity by scrubbing a paused timeline, per-element occlusion of both text and controls at five widths, and the enlarged view opened by pointer and by keyboard |
|
|
@@ -532,15 +558,16 @@ so the pattern is in the data, not just in this paragraph.
|
|
|
532
558
|
| `data/conversion-batch.csv` | 19 | **converted, built and checked live, one page after another** - every Elementor page of a production site through the converter, with per-page element and content counts |
|
|
533
559
|
| `data/token-benchmark.csv` | 6 | **measured with tiktoken** - the same six lookups priced three ways: reading the plugin source, loading every table, querying `mo.py`. 71-99.5% fewer tokens than the source and 99.6%+ fewer than the tables, which total 259,539 - never load them, query them |
|
|
534
560
|
| `data/slider-verification.csv` | 30 | **driven live** - two sliders, one autoplaying and one a carousel: advance, arrows, bullets, keyboard, reduced motion |
|
|
535
|
-
| `data/navigation-verification.csv` |
|
|
561
|
+
| `data/navigation-verification.csv` | 39 | **fetched and opened live** - every menu item is a real `<a href>`, each of the demo's twelve pages answers 200, every in-page anchor it links to exists, and no page scrolls sideways at 390 / 768 / 1280 |
|
|
536
562
|
| `data/page-modal-verification.csv` | 19 | **read live** - one modal per page, and what each one's trigger, run rule, memory scope and dismissal policy actually came out as |
|
|
537
|
-
| `data/dialog-verification.csv` | 19 | **driven live** - the 1.0.
|
|
563
|
+
| `data/dialog-verification.csv` | 19 | **driven live** - the modal (re-run on 1.0.10), its triggers, its run rules and the memory actions, each exercised in a real browser |
|
|
538
564
|
| `data/dialog-form-verification.csv` | 49 | **driven live** - the same three nodes made into five FORMS (sheet, drawer, corner, takeover, gate), each re-opened at 390px and 768px; also where `pickOne` on a click turned out to be a latch rather than a lottery |
|
|
565
|
+
| `data/popover-verification.csv` | 37 | **driven live** - 1.0.10's popover: every host a `<div popover=manual>`, a pageLoad notice that leaves the page scrollable and clickable, closedby honoured per policy, anchored placement against the trigger and against another element, the nine screen cells, keepInView flipping and the `___popover--flipped` state applying, a three-step tour advanced by afterClose and ended by interactionSuspend, and a modal whose host sets `display:flex` and still hides when closed |
|
|
539
566
|
| `data/token-verification.csv` | 15 | **driven live** - every `:root` custom property declared once, non-empty, and resolved by something on the page; a token nothing points at is a token that is not working |
|
|
540
|
-
| `data/mobile-audit.csv` |
|
|
567
|
+
| `data/mobile-audit.csv` | 68 | **driven live** - what a sideways-scroll check cannot see: type under the legible floor, controls too small to hit, a grid that never collapsed, content escaping its box |
|
|
541
568
|
| `data/component-wall-verification.csv` | 26 | **driven live** - tabs switched, an accordion opened, a form's fields and Mosaic's own honeypot, and an OpenStreetMap asserted on the coordinates it was GIVEN rather than the default it falls back to |
|
|
542
|
-
| `data/form-surface-verification.csv` |
|
|
543
|
-
| `data/content-loop-verification.csv` |
|
|
569
|
+
| `data/form-surface-verification.csv` | 18 | **driven live** - every field type Mosaic ships in one form: select with labelled options, radio and checkbox groups, file upload, and the browser's own validation refusing an empty submit |
|
|
570
|
+
| `data/content-loop-verification.csv` | 15 | **driven live** - a slider, a tab bar, a list and a paginated archive whose children all come from one authored template repeated per post; the pagination is clicked and the rows asserted to CHANGE |
|
|
544
571
|
| `data/custom-fields-verification.csv` | 62 | **rendered live** - ACF and Meta Box fields of every common type read back through `@VAR` / `@LOOP` off the delivered page, loops included |
|
|
545
572
|
| `data/theme-zip-verification.csv` | 22 | **round-tripped live** - Mosaic's own ZIP export imported in test mode and compared to its source, table by table and tree by tree |
|
|
546
573
|
| `data/node-type-notes.csv` | 8 | where a sweep outcome is true but misleading on its own, why. Surfaced by `mo.py type` |
|
|
@@ -549,11 +576,11 @@ so the pattern is in the data, not just in this paragraph.
|
|
|
549
576
|
| `data/variants.csv` | 156 | **live** — the variant catalog (Mosaic's built-in element classes); their IDs are what a `variant` record must use, and `class_name` is what the element emits |
|
|
550
577
|
| `data/dynamic-variables.csv` | 74 | source — every `@VAR('ns/name')` expression, by namespace |
|
|
551
578
|
| `data/evaluator-functions.csv` | 19 | source — the `@` functions with their arity |
|
|
552
|
-
| `data/interaction-types.csv` |
|
|
579
|
+
| `data/interaction-types.csv` | 16 | source — trigger types, `timed` vs `progress`; 1.0.9 added exitIntent, scrollDepth and modal, 1.0.10 adds popover (Popover visibility change: show / beforeClose / afterClose) |
|
|
553
580
|
| `data/animatable-properties.csv` | 22 | source — what a keyframe can drive (**not** the same set as the style properties) |
|
|
554
581
|
| `data/condition-subjects.csv` | 59 | **live** — condition subjects per context |
|
|
555
|
-
| `data/condition-comparators.csv` | 12 | **live** — comparators and their operator sets |
|
|
556
|
-
| `data/pluggables.csv` |
|
|
582
|
+
| `data/condition-comparators.csv` | 12 | **live** — comparators and their operator sets, captured on 1.0.9; the two date rows carry 1.0.10's four operators (after, after-or-equal, before, before-or-equal) from its source |
|
|
583
|
+
| `data/pluggables.csv` | 261 | source — every `setID()` by registry |
|
|
557
584
|
| `data/rest-routes.csv` | 115 | **live** — method, path, args |
|
|
558
585
|
| `data/db-columns.csv` | 210 | **live** — every column of all 23 tables |
|
|
559
586
|
|
|
@@ -644,7 +671,7 @@ post — `build_all.py` resets first for that reason.
|
|
|
644
671
|
|
|
645
672
|
## Facts worth knowing before you look anything up
|
|
646
673
|
|
|
647
|
-
- **The REST namespace contains the plugin version** (`/wp-json/mosaic/v1.0.
|
|
674
|
+
- **The REST namespace contains the plugin version** (`/wp-json/mosaic/v1.0.10`). Read
|
|
648
675
|
it from `mosaicOptions.rest_api_url`, never hardcode. After a plugin update the
|
|
649
676
|
editor namespace is GONE until the data upgrade has run; only
|
|
650
677
|
`mosaic/<dataVersion>/<version>/upgrade` answers. `tools/data_upgrade.py`.
|
|
@@ -745,6 +772,22 @@ post — `build_all.py` resets first for that reason.
|
|
|
745
772
|
`@media` blocks together; the old `mosaic-theme-block-editor-styles_<bp>-inline-css`
|
|
746
773
|
ids are gone. And an element whose styles compile to nothing is emitted with
|
|
747
774
|
no generated class at all, so "no `_token`" no longer means "did not render".
|
|
775
|
+
- **Since 1.0.10 the modal is a Popover-API host in the top layer.** `<dialog
|
|
776
|
+
popover="manual">`; `dialog.open` is always false (read `:popover-open` or
|
|
777
|
+
`data-mosaic-dialog-state`), the controller has `requestClose()` and no `close()`,
|
|
778
|
+
and the closed state is `display:none !important` - so `display` on a modal host,
|
|
779
|
+
a pin-it-open bug on 1.0.9, is safe now. z-index cannot put anything above it.
|
|
780
|
+
- **`popover` is the non-blocking dialog (1.0.10)**: no overlay, no children
|
|
781
|
+
required, `closedby` defaults to `nothing`, `positioning` is `screen` (nine cells)
|
|
782
|
+
or `element` (side / align / keepInView / anchor - no anchor = its trigger).
|
|
783
|
+
Actions `popoverOpen` / `popoverClose` / `popoverToggle`; trigger `popover` with
|
|
784
|
+
slots `show` / `beforeClose` / `afterClose`; style state `___popover--flipped`.
|
|
785
|
+
**A dialog opened from inside another dialog is its child and closes with it, and
|
|
786
|
+
closing a popover suspends the interactions inside it** - so a sequence advances
|
|
787
|
+
on the step's own `afterClose`, never on a button that opens the next step.
|
|
788
|
+
references/dialog-and-triggers.md
|
|
789
|
+
- **`scrollDepth`'s action slot is `reached` since 1.0.10** (plus `returned`). An
|
|
790
|
+
action stored under the old slot name `scrollDepth` is kept and never runs.
|
|
748
791
|
- **A custom field is `@VAR('post/meta_<key>')`, and a multi-value one is a LOOP.**
|
|
749
792
|
ACF and Meta Box both, plus bare post meta. Derived properties hang off the
|
|
750
793
|
name with two underscores (`meta_k__label`, `__url`, `__id`); an ACF group is
|
|
@@ -814,7 +857,8 @@ post — `build_all.py` resets first for that reason.
|
|
|
814
857
|
| `theme_delete.php` | remove a theme completely through the plugin's own routine; refuses the live one |
|
|
815
858
|
| `verify_slider.py` | the slider in a real browser: does it advance, do the arrows and bullets drive it, does the keyboard, does it stop when motion is not wanted - `--label`/`--append` put several sliders in one table, which is where a carousel and a plain slider can be held against each other |
|
|
816
859
|
| `verify_navigation.py` | a multi-page site: is every menu item a real `<a href>`, does every page answer 200 (a template that was never bound answers 406 with an empty body, which only a logged-out visitor sees), and with `--viewports` does any page scroll SIDEWAYS - the one question no per-page checker asks - and whether every in-page `#fragment` resolves ON THE PAGE THAT CARRIES IT, which an HTTP check cannot see: a bare `#services` in a SHARED header fetches the current page, answers 200 everywhere, and does nothing on every page but the one that has that section |
|
|
817
|
-
| `verify_dialog.py` | the 1.0.9
|
|
860
|
+
| `verify_dialog.py` | the modal in a real browser (1.0.9 and 1.0.10 alike: open is read as `:popover-open` or `dialog.open`): does it open, close, answer Esc, remember, cap - and does an OpenStreetMap carry the coordinates it was given |
|
|
861
|
+
| `verify_popovers.py` | 1.0.10's popover in a real browser: opens, lands where its positioning says, blocks nothing, closes the way closedby says, flips, chains, and ends - every check reads `:popover-open`, never an attribute |
|
|
818
862
|
| `verify_dialog_lab.py` | the question after "does the modal work": can three nodes be made into a bottom sheet, a side drawer, a corner notice, a full takeover and a gate with no way out - and does each one still fit at phone width, which the page's own width check cannot see |
|
|
819
863
|
| `verify_tokens.py` | the design tokens as the BROWSER resolved them: every `:root` property declared once (a changed value does not retire the old one), non-empty, and actually pointed at by something - a wrong `skinsData` shape still emits the declaration and serves white |
|
|
820
864
|
| `verify_components.py` | presses the interactive components on a page and asserts the RESULT - a pane actually swapped, an accordion item actually opened, the map carries the coordinates it was given - because "these all work" is worth what the last press proved |
|
|
@@ -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.
|
|
23
|
+
"version": "1.31.0"
|
|
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.
|
|
23
|
+
"version": "1.31.0"
|
|
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.
|
|
23
|
+
"version": "1.31.0"
|
|
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.
|
|
23
|
+
"version": "1.31.0"
|
|
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.
|
|
23
|
+
"version": "1.31.0"
|
|
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,
|
|
@@ -1906,8 +1906,8 @@ _t,mk-pan-loop,display,flex,flex,ok
|
|
|
1906
1906
|
_t,mk-pan-loop,columnGap,56px,56px,ok
|
|
1907
1907
|
_t,mk-pan-loop,alignItems,baseline,baseline,ok
|
|
1908
1908
|
_t,mk-pan-loop,customDeclarations:white-space,nowrap,no computed value,not-comparable
|
|
1909
|
-
_t,mk-pan-loop,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
1910
|
-
_t,mk-pan-track,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
1909
|
+
_t,mk-pan-loop,customDeclarations:width,max-content,max-content resolves to a used value (3764.03px),not-comparable
|
|
1910
|
+
_t,mk-pan-track,customDeclarations:width,max-content,max-content resolves to a used value (3764.03px),not-comparable
|
|
1911
1911
|
_t,mk-plate-in,width,100%,viewport- or parent-relative,not-comparable
|
|
1912
1912
|
_t,mk-plate-in,maxWidth,1240px,1240px,ok
|
|
1913
1913
|
_t,mk-plate-in,marginLeft,auto,auto resolves to a used value (0px),not-comparable
|
|
@@ -1983,12 +1983,12 @@ _t,mk-prod-s-0,marginTop,14px,14px,ok
|
|
|
1983
1983
|
_t,mk-prod-s-0,customDeclarations:border,"1px solid rgba(255,90,54,.6)",no computed value,not-comparable
|
|
1984
1984
|
_t,mk-prod-s-0,customDeclarations:padding,5px 10px,no computed value,not-comparable
|
|
1985
1985
|
_t,mk-prod-s-0,customDeclarations:display,inline-block,inline-block,ok
|
|
1986
|
-
_t,mk-prod-s-0,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
1986
|
+
_t,mk-prod-s-0,customDeclarations:width,max-content,max-content resolves to a used value (99.7656px),not-comparable
|
|
1987
1987
|
_t,mk-prod-s-1,marginTop,14px,14px,ok
|
|
1988
1988
|
_t,mk-prod-s-1,customDeclarations:border,"1px solid rgba(255,90,54,.6)",no computed value,not-comparable
|
|
1989
1989
|
_t,mk-prod-s-1,customDeclarations:padding,5px 10px,no computed value,not-comparable
|
|
1990
1990
|
_t,mk-prod-s-1,customDeclarations:display,inline-block,inline-block,ok
|
|
1991
|
-
_t,mk-prod-s-1,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
1991
|
+
_t,mk-prod-s-1,customDeclarations:width,max-content,max-content resolves to a used value (82.4844px),not-comparable
|
|
1992
1992
|
_t,mk-spec,display,grid,grid,ok
|
|
1993
1993
|
_t,mk-spec,gridCols,"repeat(2, 1fr)",422px 422px,ok
|
|
1994
1994
|
_t,mk-spec,columnGap,0px,0px,ok
|
|
@@ -2048,28 +2048,28 @@ _t,mk-spec2-in,marginRight,auto,auto resolves to a used value (0px),not-comparab
|
|
|
2048
2048
|
_t,mk-spec2-pad,paddingTop,88px,88px,ok
|
|
2049
2049
|
_t,mk-spec2-pad,paddingBottom,88px,88px,ok
|
|
2050
2050
|
_t,mk-spec2-r-0,display,grid,grid,ok
|
|
2051
|
-
_t,mk-spec2-r-0,gridCols,1fr auto,
|
|
2051
|
+
_t,mk-spec2-r-0,gridCols,1fr auto,615.359px 200.641px,ok
|
|
2052
2052
|
_t,mk-spec2-r-0,columnGap,28px,28px,ok
|
|
2053
2053
|
_t,mk-spec2-r-0,alignItems,baseline,baseline,ok
|
|
2054
2054
|
_t,mk-spec2-r-0,paddingTop,20px,20px,ok
|
|
2055
2055
|
_t,mk-spec2-r-0,paddingBottom,20px,20px,ok
|
|
2056
2056
|
_t,mk-spec2-r-0,customDeclarations:border-top,"1px solid rgba(250,250,247,.18)",no computed value,not-comparable
|
|
2057
2057
|
_t,mk-spec2-r-1,display,grid,grid,ok
|
|
2058
|
-
_t,mk-spec2-r-1,gridCols,1fr auto,
|
|
2058
|
+
_t,mk-spec2-r-1,gridCols,1fr auto,624.469px 191.531px,ok
|
|
2059
2059
|
_t,mk-spec2-r-1,columnGap,28px,28px,ok
|
|
2060
2060
|
_t,mk-spec2-r-1,alignItems,baseline,baseline,ok
|
|
2061
2061
|
_t,mk-spec2-r-1,paddingTop,20px,20px,ok
|
|
2062
2062
|
_t,mk-spec2-r-1,paddingBottom,20px,20px,ok
|
|
2063
2063
|
_t,mk-spec2-r-1,customDeclarations:border-top,"1px solid rgba(250,250,247,.18)",no computed value,not-comparable
|
|
2064
2064
|
_t,mk-spec2-r-2,display,grid,grid,ok
|
|
2065
|
-
_t,mk-spec2-r-2,gridCols,1fr auto,
|
|
2065
|
+
_t,mk-spec2-r-2,gridCols,1fr auto,615.359px 200.641px,ok
|
|
2066
2066
|
_t,mk-spec2-r-2,columnGap,28px,28px,ok
|
|
2067
2067
|
_t,mk-spec2-r-2,alignItems,baseline,baseline,ok
|
|
2068
2068
|
_t,mk-spec2-r-2,paddingTop,20px,20px,ok
|
|
2069
2069
|
_t,mk-spec2-r-2,paddingBottom,20px,20px,ok
|
|
2070
2070
|
_t,mk-spec2-r-2,customDeclarations:border-top,"1px solid rgba(250,250,247,.18)",no computed value,not-comparable
|
|
2071
2071
|
_t,mk-spec2-r-3,display,grid,grid,ok
|
|
2072
|
-
_t,mk-spec2-r-3,gridCols,1fr auto,
|
|
2072
|
+
_t,mk-spec2-r-3,gridCols,1fr auto,615.359px 200.641px,ok
|
|
2073
2073
|
_t,mk-spec2-r-3,columnGap,28px,28px,ok
|
|
2074
2074
|
_t,mk-spec2-r-3,alignItems,baseline,baseline,ok
|
|
2075
2075
|
_t,mk-spec2-r-3,paddingTop,20px,20px,ok
|
|
@@ -3235,8 +3235,8 @@ _m,mk-pan-loop,display,flex,flex,ok
|
|
|
3235
3235
|
_m,mk-pan-loop,columnGap,30px,30px,ok
|
|
3236
3236
|
_m,mk-pan-loop,alignItems,baseline,baseline,ok
|
|
3237
3237
|
_m,mk-pan-loop,customDeclarations:white-space,nowrap,no computed value,not-comparable
|
|
3238
|
-
_m,mk-pan-loop,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
3239
|
-
_m,mk-pan-track,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
3238
|
+
_m,mk-pan-loop,customDeclarations:width,max-content,max-content resolves to a used value (2474.22px),not-comparable
|
|
3239
|
+
_m,mk-pan-track,customDeclarations:width,max-content,max-content resolves to a used value (2474.22px),not-comparable
|
|
3240
3240
|
_m,mk-plate-in,width,100%,viewport- or parent-relative,not-comparable
|
|
3241
3241
|
_m,mk-plate-in,maxWidth,1240px,1240px,ok
|
|
3242
3242
|
_m,mk-plate-in,marginLeft,auto,auto resolves to a used value (0px),not-comparable
|
|
@@ -3313,12 +3313,12 @@ _m,mk-prod-s-0,marginTop,14px,14px,ok
|
|
|
3313
3313
|
_m,mk-prod-s-0,customDeclarations:border,"1px solid rgba(255,90,54,.6)",no computed value,not-comparable
|
|
3314
3314
|
_m,mk-prod-s-0,customDeclarations:padding,5px 10px,no computed value,not-comparable
|
|
3315
3315
|
_m,mk-prod-s-0,customDeclarations:display,inline-block,inline-block,ok
|
|
3316
|
-
_m,mk-prod-s-0,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
3316
|
+
_m,mk-prod-s-0,customDeclarations:width,max-content,max-content resolves to a used value (99.7656px),not-comparable
|
|
3317
3317
|
_m,mk-prod-s-1,marginTop,14px,14px,ok
|
|
3318
3318
|
_m,mk-prod-s-1,customDeclarations:border,"1px solid rgba(255,90,54,.6)",no computed value,not-comparable
|
|
3319
3319
|
_m,mk-prod-s-1,customDeclarations:padding,5px 10px,no computed value,not-comparable
|
|
3320
3320
|
_m,mk-prod-s-1,customDeclarations:display,inline-block,inline-block,ok
|
|
3321
|
-
_m,mk-prod-s-1,customDeclarations:width,max-content,max-content resolves to a used value (
|
|
3321
|
+
_m,mk-prod-s-1,customDeclarations:width,max-content,max-content resolves to a used value (82.4844px),not-comparable
|
|
3322
3322
|
_m,mk-spec,display,grid,grid,ok
|
|
3323
3323
|
_m,mk-spec,gridCols,"repeat(2, 1fr)",177px 177px,ok
|
|
3324
3324
|
_m,mk-spec,columnGap,0px,0px,ok
|
|
@@ -18,7 +18,7 @@ MEDIA/icons_inline,PASS,"3 inline <svg> - `icon` takes RAW SVG in its `svg` prop
|
|
|
18
18
|
WORDPRESS/shortcode_ran,PASS,"3 items from the shortcode - this is WooCommerce's own output, not a reimplementation"
|
|
19
19
|
MULTISTEP,SKIPPED,not on this page
|
|
20
20
|
COMPONENT/instances,PASS,"3 instances: ['cs-0-cs-card', 'cs-1-cs-card', 'cs-2-cs-card']"
|
|
21
|
-
COMPONENT/one_definition,PASS,"all share the generated class ['
|
|
21
|
+
COMPONENT/one_definition,PASS,"all share the generated class ['_fp'] - one definition, not 3 copies"
|
|
22
22
|
COMPONENT/content_differs,PASS,"3 instances, 3 distinct bodies - the overrides are per-instance"
|
|
23
23
|
LOOP/slider,SKIPPED,not on this page
|
|
24
24
|
LOOP/tabs,SKIPPED,not on this page
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
context,rule_type,comparator,label,operators,settings_fields,field_types,supports_dynamic
|
|
2
2
|
element,serverCondition,text,Text,equals|not-equals|contains|not-contains|starts-with|regexp,value,text,yes
|
|
3
3
|
element,serverCondition,number,Number,equals|not-equals|greater-than|greater-than-or-equal|less-than|less-than-or-equal,value,number,yes
|
|
4
|
-
element,serverCondition,date,Date,after|before,value,dateTime,yes
|
|
4
|
+
element,serverCondition,date,Date,after|after-or-equal|before|before-or-equal,value,dateTime,yes
|
|
5
5
|
formAction,serverCondition,text,Text,equals|not-equals|contains|not-contains|starts-with|regexp,value,text,yes
|
|
6
6
|
formAction,serverCondition,number,Number,equals|not-equals|greater-than|greater-than-or-equal|less-than|less-than-or-equal,value,number,yes
|
|
7
|
-
formAction,serverCondition,date,Date,after|before,value,dateTime,yes
|
|
7
|
+
formAction,serverCondition,date,Date,after|after-or-equal|before|before-or-equal,value,dateTime,yes
|
|
8
8
|
interaction,serverCondition,text,Text,equals|not-equals|contains|not-contains|starts-with|regexp,value,text,no
|
|
9
9
|
interaction,serverCondition,number,Number,equals|not-equals|greater-than|greater-than-or-equal|less-than|less-than-or-equal,value,number,no
|
|
10
10
|
interaction,browserCondition,text,Text,equals|not-equals|contains|not-contains|starts-with,value,text,no
|
|
@@ -2,12 +2,15 @@ check,result,detail
|
|
|
2
2
|
TABS,SKIPPED,not on this page
|
|
3
3
|
ACCORDION,SKIPPED,not on this page
|
|
4
4
|
FORM,SKIPPED,not on this page
|
|
5
|
+
NAVBAR,SKIPPED,not on this page
|
|
6
|
+
MEDIA,SKIPPED,not on this page
|
|
7
|
+
WORDPRESS,SKIPPED,not on this page
|
|
5
8
|
MULTISTEP,SKIPPED,not on this page
|
|
6
9
|
COMPONENT/instances,SKIPPED,fewer than two on this page
|
|
7
10
|
LOOP/slider,PASS,6 slides from one authored slider-slide
|
|
8
11
|
LOOP/tabs,PASS,4 tabs from one authored tabs-tab
|
|
9
12
|
LOOP/tab_labels_intact,PASS,"no replacement characters - @substr counts bytes, so a length that is not a multiple of the encoding cuts a glyph in half"
|
|
10
|
-
LOOP/pagination_links,PASS,"3 page links: ['
|
|
13
|
+
LOOP/pagination_links,PASS,"3 page links: ['notes=1', 'notes=2', 'notes=3']"
|
|
11
14
|
LOOP/pagination_key_is_safe,PASS,paginationKey does not collide with a WordPress query var
|
|
12
15
|
LOOP/pagination_changes_rows,PASS,page 1 3 -> page 2 3
|
|
13
16
|
MAP,SKIPPED,not on this page
|