mosaic-headless 1.2.1 → 1.3.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 CHANGED
@@ -20,6 +20,17 @@ fractional-index の文字列。エディタはこのモデルの一クライア
20
20
  **ノードタイプ、プロパティ名、列挙値、スタイルキー、Free/Pro の判断を記憶で書かないこと。
21
21
  `data/` を引くこと。**
22
22
 
23
+ しかも grep ではなく `mo.py` で引く。grep は打った質問には答えるが、本当に抱えている
24
+ 質問には答えない。`accordion-content` を grep すればその型が存在することは分かるが、
25
+ それを置くと commit は綺麗に通り、そのあと公開ページ全体が 54 バイトのエラー文字列に
26
+ なることは教えてくれない。
27
+
28
+ ```bash
29
+ python tools/mo.py type accordion-content # 1 つの型を、全ライブスイープに接続して表示
30
+ python tools/mo.py check div text button # 危険な型・未知の型があれば exit 1
31
+ python tools/mo.py style --grouped # 単独設定では必ず効かない 20 個
32
+ ```
33
+
23
34
  そのうえでページを見る。Mosaic の失敗の仕方は 4 通りあり、
24
35
  **HTTP ステータスが変わるのはそのうち 1 つだけ**:
25
36
 
@@ -29,10 +40,12 @@ commit 中の PHP fatal HTTP 500 (122 タイプ中 15、素の div の
29
40
  構造的に不正なノード HTTP 200、コミット済み、DB に行もある。そして
30
41
  公開ページ全体が 54 バイトのエラー文字列になる
31
42
  値の「形」が違う HTTP 200、保存される。ただし CSS ルールが存在しない
43
+ ルールは正しいが結果が違う HTTP 200、スタイルシートにあり、内容も正しい。それでも
44
+ ブラウザは別の値を計算する
32
45
  URL に対応するテンプレなし HTTP 406、未ログインには空の body
33
46
  ```
34
47
 
35
- **commit の成功は、ページが動いている証拠にはならない。**
48
+ **commit の成功も、正しいスタイルシートも、ページが動いている証拠にはならない。**
36
49
 
37
50
  ## 何を、どう検証したか
38
51
 
@@ -46,6 +59,8 @@ URL に対応するテンプレなし HTTP 406、未ログインには空の b
46
59
  | **スタイルプロパティ** | 98 / 98 を実ページに書き、コンパイル済み CSS と照合:58 COMPILED、18 ABSENT、21 SKIPPED |
47
60
  | **ノードプロパティ** | 181 / 181 を、各プロパティ自身の validator chain から導いた値で再測定:35 APPLIED、42 NO_EFFECT、55 NO_HOST、47 SKIPPED |
48
61
  | **レスポンシブ** | 2 サイト計 576 件の `_t`/`_m` 宣言を、サイトが実際に配信したスタイルシートに対して 1 件ずつ断言 — 全件検証済み |
62
+ | **ブラウザ** | 配信されたページを Chromium の 3 つのビューポートで計算スタイル 2,237 件読み取り:1,661 件が一致、576 件は比較不能として明示、**上書き 0 件** |
63
+ | **デザイン監査** | コントラスト、フォントフォールバック、CJK の字送り、横溢れ、テキストの切れ、1 行の文字数 — ブラウザ上で実行、**指摘 0 件** |
49
64
  | **テーマの書き出し/読み込み** | 往復検証済み:テーマ全体を書き出し、コピーとして読み込み、そのコピーがバイト単位で同一のページを配信 |
50
65
  | **実測** | REST ルート 114、element class 151、条件サブジェクト 59、23 テーブル / 206 カラム |
51
66
 
package/README.ko.md CHANGED
@@ -20,6 +20,17 @@ fractional-index 문자열이다. 에디터는 이 모델의 한 클라이언트
20
20
  **노드 타입, 속성 이름, 열거값, 스타일 키, Free/Pro 판단을 기억으로 쓰지 말 것.
21
21
  `data/`에서 찾아볼 것.**
22
22
 
23
+ 그리고 grep이 아니라 `mo.py`로 찾을 것. grep은 입력한 질문에 답할 뿐, 실제로 품고 있는
24
+ 질문에는 답하지 않는다. `accordion-content`를 grep하면 그 타입이 존재한다는 것은 알 수
25
+ 있지만, 그것을 배치하면 commit은 깨끗하게 통과하고 그다음 공개 페이지 전체가 54바이트
26
+ 에러 문자열이 된다는 사실은 알려주지 않는다.
27
+
28
+ ```bash
29
+ python tools/mo.py type accordion-content # 타입 하나를 모든 라이브 스윕과 연결해 출력
30
+ python tools/mo.py check div text button # 위험하거나 존재하지 않는 타입이면 exit 1
31
+ python tools/mo.py style --grouped # 단독으로 설정하면 반드시 무효인 20개
32
+ ```
33
+
23
34
  그리고 페이지를 확인한다. Mosaic의 실패 방식은 네 가지이고,
24
35
  **그중 HTTP 상태 코드가 바뀌는 것은 하나뿐이다**:
25
36
 
@@ -29,10 +40,12 @@ commit 중 PHP fatal HTTP 500 (122개 타입 중 15개, 맨 div 안에
29
40
  구조적으로 잘못된 노드 HTTP 200, 커밋됨, DB에 행도 있음. 그리고
30
41
  공개 페이지 전체가 54바이트 에러 문자열이 된다
31
42
  값의 "모양"이 틀림 HTTP 200, 저장됨. 다만 CSS 규칙이 존재하지 않는다
43
+ 규칙은 맞는데 결과가 다름 HTTP 200, 스타일시트에 있고 내용도 맞다. 그런데 브라우저가
44
+ 계산해내는 값은 다른 것이다
32
45
  URL에 맞는 템플릿 없음 HTTP 406, 로그인하지 않은 사용자에게는 빈 body
33
46
  ```
34
47
 
35
- **commit 성공은 페이지가 동작한다는 증거가 아니다.**
48
+ **commit 성공도, 올바른 스타일시트도 페이지가 동작한다는 증거가 아니다.**
36
49
 
37
50
  ## 무엇을, 어떻게 검증했는가
38
51
 
@@ -46,6 +59,8 @@ URL에 맞는 템플릿 없음 HTTP 406, 로그인하지 않은 사용자
46
59
  | **스타일 속성** | 98 / 98을 실제 페이지에 쓰고 컴파일된 CSS와 대조: 58 COMPILED, 18 ABSENT, 21 SKIPPED |
47
60
  | **노드 속성** | 181 / 181을 각 속성 자신의 validator chain에서 도출한 값으로 재측정: 35 APPLIED, 42 NO_EFFECT, 55 NO_HOST, 47 SKIPPED |
48
61
  | **반응형** | 두 사이트 합쳐 576개의 `_t`/`_m` 선언을, 사이트가 실제로 내보낸 스타일시트에 대해 하나씩 단언 — 전부 검증됨 |
62
+ | **브라우저** | 전달된 페이지를 Chromium의 세 가지 뷰포트에서 계산 스타일 2,237건 판독: 1,661건 일치, 576건은 비교 불가로 명시, **덮어쓰기 0건** |
63
+ | **디자인 감사** | 명암비, 폰트 폴백, CJK 자간, 가로 넘침, 텍스트 잘림, 한 줄 글자 수 — 브라우저에서 실행, **지적 0건** |
49
64
  | **테마 내보내기/가져오기** | 왕복 검증: 테마 전체를 내보내 사본으로 가져왔고, 사본이 바이트 단위로 동일한 페이지를 제공 |
50
65
  | **실측** | REST 라우트 114개, element class 151개, 조건 주체 59개, 23개 테이블 / 206개 컬럼 |
51
66
 
package/README.md CHANGED
@@ -20,6 +20,17 @@ read off the source.
20
20
  **Never write a node type, property name, enum value, style key or Free/Pro claim
21
21
  from memory. Look it up in `data/`.**
22
22
 
23
+ And look it up with `mo.py`, not grep. Grep answers the question you typed; it does
24
+ not answer the question you have. Ask grep about `accordion-content` and it confirms
25
+ the type exists. It does not mention that placing one commits cleanly and then
26
+ reduces the whole public page to a 54-byte error string.
27
+
28
+ ```bash
29
+ python tools/mo.py type accordion-content # one type, joined to every live sweep
30
+ python tools/mo.py check div text button # exits 1 on an unsafe or unknown type
31
+ python tools/mo.py style --grouped # the 20 that are inert set on their own
32
+ ```
33
+
23
34
  Then check the page. Mosaic has four failure modes and **only one of them changes the
24
35
  HTTP status code**:
25
36
 
@@ -29,10 +40,13 @@ PHP fatal during commit HTTP 500 (15 of 122 types do this from a plain div)
29
40
  structurally invalid node HTTP 200, committed, row in the DB, and the whole
30
41
  public page becomes a 54-byte error string
31
42
  wrong value SHAPE HTTP 200, stored, and the CSS rule is simply absent
43
+ right rule, wrong result HTTP 200, in the stylesheet, correct, and the BROWSER
44
+ computes something else
32
45
  no template for the URL HTTP 406 with an EMPTY BODY for anyone not logged in
33
46
  ```
34
47
 
35
- A successful commit is not evidence of a working page.
48
+ A successful commit is not evidence of a working page, and neither is a correct
49
+ stylesheet.
36
50
 
37
51
  ## What was verified, and how
38
52
 
@@ -46,6 +60,8 @@ factories, so Pro types register and render regardless.
46
60
  | **style properties** | 98 / 98 written to a live page and checked against the compiled CSS: 58 COMPILED, 18 ABSENT, 21 SKIPPED |
47
61
  | **node properties** | 181 / 181 re-probed with a value shaped by each property's own validator chain: 35 APPLIED, 42 NO_EFFECT, 55 NO_HOST, 47 SKIPPED |
48
62
  | **responsive** | 576 `_t`/`_m` declarations across two sites asserted against the stylesheet the site actually served — all verified |
63
+ | **browser** | 2,237 computed-style readings on the delivered page in Chromium at three viewports: 1,661 compared and agreed, 576 not-comparable and labelled, **0 overridden** |
64
+ | **design audit** | contrast, font fallback, CJK tracking, overflow, clipped text, line measure — run in the browser, **0 findings** |
49
65
  | **theme export/import** | round-tripped: a full theme exported, re-imported as a copy, and the copy served byte-identical pages |
50
66
  | **measured live** | 114 REST routes, 151 element classes, 59 condition subjects, 23 tables / 206 columns |
51
67
 
package/README.zh-TW.md CHANGED
@@ -17,6 +17,16 @@ Mosaic 把一個頁面放在 **23 張自訂資料表**裡,不在 `post_content
17
17
 
18
18
  **絕不憑印象寫節點型別、屬性名稱、列舉值、樣式鍵或 Free/Pro 的判斷。到 `data/` 裡查。**
19
19
 
20
+ 而且要用 `mo.py` 查,不要用 grep。grep 回答你打出來的問題,不回答你真正的問題:
21
+ 問它 `accordion-content`,它確認這個型別存在,但不會提到放一個下去會乾淨地寫入、
22
+ 然後把整個公開頁面變成一段 54 bytes 的錯誤字串。
23
+
24
+ ```bash
25
+ python tools/mo.py type accordion-content # 一個型別,接上所有線上掃描結果
26
+ python tools/mo.py check div text button # 型別不安全或不存在就 exit 1
27
+ python tools/mo.py style --grouped # 那 20 個單獨設定必然無效的屬性
28
+ ```
29
+
20
30
  然後去看頁面。Mosaic 有四種失效模式,**其中只有一種會改變 HTTP 狀態碼**:
21
31
 
22
32
  ```
@@ -25,10 +35,11 @@ commit 時 PHP fatal HTTP 500 (122 種型別裡有 15 種,光放在 div
25
35
  結構無效的節點 HTTP 200、已寫入、資料庫有那一列,然後整個公開頁面
26
36
  變成一段 54 bytes 的錯誤字串
27
37
  值的「形狀」錯誤 HTTP 200、已儲存,而那條 CSS 規則就是不存在
38
+ 規則對,結果不對 HTTP 200、在樣式表裡、內容正確,而瀏覽器算出來是另一回事
28
39
  該網址沒有對應範本 HTTP 406,而且對未登入者是空白 body
29
40
  ```
30
41
 
31
- **commit 成功不能當作頁面正常的證據。**
42
+ **commit 成功不能當作頁面正常的證據,樣式表正確也不能。**
32
43
 
33
44
  ## 驗證了什麼,怎麼驗的
34
45
 
@@ -41,6 +52,8 @@ commit 時 PHP fatal HTTP 500 (122 種型別裡有 15 種,光放在 div
41
52
  | **樣式屬性** | 98 / 98 寫進真實頁面並對照編譯後的 CSS:58 COMPILED、18 ABSENT、21 SKIPPED |
42
53
  | **節點屬性** | 181 / 181,用每個屬性自己的 validator chain 推導出的值重測:35 APPLIED、42 NO_EFFECT、55 NO_HOST、47 SKIPPED |
43
54
  | **響應式** | 兩個站共 576 條 `_t`/`_m` 宣告,對照網站實際送出的樣式表逐條斷言——全數通過 |
55
+ | **瀏覽器** | 在 Chromium 三個視窗寬度上對交付頁面做 2,237 次計算樣式讀取:1,661 條比對相符、576 條標為無法比對、**0 條被覆蓋** |
56
+ | **設計稽核** | 對比度、字體回退、CJK 字距、水平溢出、文字裁切、每行字數——在瀏覽器裡跑,**0 項發現** |
44
57
  | **主題匯出/匯入** | 完整來回驗證:匯出整個主題、以副本身分匯入,副本送出的頁面逐位元組相同 |
45
58
  | **線上量測** | 114 條 REST 路由、151 個 element class、59 個條件主體、23 張表 / 206 個欄位 |
46
59
 
package/SKILL.md CHANGED
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: "mosaic-headless"
3
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.
4
+ Build and modify Mosaic Pro (Nextend) sites by writing the underlying data model directly - no visual editor, no DOM. Query the real surface with `mo.py`, which joins every source table to the live sweeps so a lookup leads with the measured verdict rather than the declaration (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, nine designed pages built through the tables themselves, and the delivered page re-read in Chromium at three viewports so a rule that is present, correct and still wrong cannot pass.
5
5
  license: "MIT"
6
6
  author: "moksa (https://moksaweb.com)"
7
- version: "1.2.1"
7
+ version: "1.3.0"
8
8
  ---
9
9
 
10
10
  # Headless Mosaic
@@ -21,6 +21,34 @@ apply — `references/vs-elementor-gutenberg.md` says which skill does.
21
21
  **Never write a node type, property name, enum value, style key or Free/Pro claim
22
22
  from memory. Look it up in `data/`.**
23
23
 
24
+ And look it up with `mo.py`, not with grep. Grep answers the question you typed;
25
+ it does not answer the question you have. Ask grep about `accordion-content` and it
26
+ confirms the type exists. It does not mention that placing one commits cleanly and
27
+ then reduces the entire public page to a 54-byte error string - which is the only
28
+ thing about that type worth knowing.
29
+
30
+ ```bash
31
+ python tools/mo.py stats # the surface, and what is unsafe
32
+ python tools/mo.py type accordion-content # ONE type, joined to every sweep
33
+ python tools/mo.py types --edition pro --safe
34
+ python tools/mo.py check div text button # exits 1 on an unsafe or unknown type
35
+ python tools/mo.py placement accordion-item # what goes inside what, both directions
36
+ python tools/mo.py prop tagName # one node property + how it was probed
37
+ python tools/mo.py props --shared # the ones every element carries
38
+ python tools/mo.py style --grouped # the 20 that are inert set on their own
39
+ python tools/mo.py css border-radius # which Mosaic key drives this CSS
40
+ python tools/mo.py states --grep hover # state IDs and their selector templates
41
+ python tools/mo.py vars --namespace post # the @VAR() surface
42
+ python tools/mo.py classes --grep Heading # element classes (theme-global)
43
+ python tools/mo.py routes --grep template
44
+ python tools/mo.py tables wp_mosaic_nodes
45
+ python tools/mo.py skeleton # a minimal valid page spec
46
+ ```
47
+
48
+ `--json` on any of them for machine-readable output. Every answer leads with the
49
+ measured verdict rather than the declaration, because on this platform the two
50
+ disagree for 52 of the 122 types.
51
+
24
52
  Then check the page. Mosaic has four failure modes and **only one of them changes the
25
53
  HTTP status code**:
26
54
 
@@ -31,6 +59,10 @@ structurally invalid node HTTP 200, committed, row in the DB, and the whole
31
59
  public page becomes a 54-byte error string
32
60
  wrong value SHAPE HTTP 200, stored, and the CSS rule is simply absent -
33
61
  or worse, compiles to `transform:none`
62
+ right rule, wrong result HTTP 200, in the stylesheet, correct, and the BROWSER
63
+ computes something else: a unit that resolves against
64
+ something you forgot, a font that cannot render the
65
+ text, a property the layout mode overrides
34
66
  no template for the URL HTTP 406 with an EMPTY BODY for anyone not logged in
35
67
  ```
36
68
 
@@ -65,8 +97,10 @@ that looks like a server problem. Two things make it easy to hit:
65
97
  is 406 - and if the build fails, it stays that way. Never activate a new theme
66
98
  as a step that can be separated from the commit that fills it.
67
99
 
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.
100
+ A successful commit is not evidence of a working page, and neither is a correct
101
+ stylesheet. Fetch the page and check its size; then run `verify_browser.py` and let
102
+ the element say what it actually got. `references/failure-modes.md` has all of them,
103
+ measured.
70
104
 
71
105
  ## What was verified, and how
72
106
 
@@ -105,6 +139,14 @@ PROPERTIES 170 probes over the declared property surface, each value asserted
105
139
  against the delivered markup and the compiled CSS separately.
106
140
  data/property-verification.csv
107
141
 
142
+ BROWSER 2,237 computed-style readings on the delivered page in Chromium, at
143
+ three viewports: every declared property vs `getComputedStyle` on the
144
+ node it targets. 1,661 compared and agreed, 576 not-comparable and
145
+ labelled as such, 0 overridden. Plus a design audit that only a browser
146
+ can run - font fallback, tracking against script, text contrast,
147
+ horizontal overflow, clipped text, line measure - currently 0 findings.
148
+ data/browser-verification.csv, data/design-audit.csv
149
+
108
150
  RWD 576 responsive declarations across two sites asserted against the
109
151
  stylesheet the site actually served - each `_t`/`_m` property matched
110
152
  to its element's generated class inside that breakpoint's own media
@@ -134,7 +176,7 @@ node types 122 / 122 swept live, one per document
134
176
  node properties 181 / 181 re-probed with a value shaped by each property's
135
177
  own validator chain: 35 APPLIED, 42 NO_EFFECT,
136
178
  2 EDITOR_ONLY, 55 NO_HOST (no rendering type
137
- declares them), 47 SKIPPED
179
+ declares them), 2 INSTRUMENT, 45 SKIPPED
138
180
  style properties 98 / 98 swept live; 58 COMPILED, 18 ABSENT, 1 NO_ELEMENT,
139
181
  21 SKIPPED (no test value could be synthesised, and
140
182
  SKIPPED is never counted as a pass)
@@ -148,6 +190,15 @@ validator chain - array for `ValidatorArray`, boolean for `ValidatorBoolean`, a
148
190
  enum member for `ValidatorAcceptedValues` - six of those NO_EFFECTs turn out to work:
149
191
  `tagName`, `target`, `rel`, `height`, `size`, `insertLocation`.
150
192
 
193
+ **A sweep cannot be its own subject.** `attrID` and `style` came back SKIPPED
194
+ because the property sweep finds each probe node BY its `attrID` and reads its
195
+ `style` back out of the compiled CSS - asking it to probe those is asking a ruler to
196
+ measure itself. But SKIPPED reads as "nobody checked", and they are in fact the two
197
+ most heavily asserted properties here: every row of `style-verification.csv` is a
198
+ `style` assertion and every row of `rwd-verification.csv` is a `style` assertion
199
+ located by `attrID`. They are labelled **INSTRUMENT**, which is not a pass either,
200
+ and the label carries the file and row count that does cover them.
201
+
151
202
  **Some properties are gated by a companion.** `target` and `rel` did nothing until
152
203
  the node also carried a `url`: `button` and `menu-link` render a `<span>` without one
153
204
  and an `<a href>` with it, so an anchor-only attribute has nothing to attach to. A
@@ -229,6 +280,9 @@ so the pattern is in the data, not just in this paragraph.
229
280
  | `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
281
  | `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
282
  | `data/rwd-verification.csv` | 576 | **checked live** - every `_t`/`_m` declaration vs the served stylesheet, with status per row |
283
+ | `data/browser-verification.csv` | 2237 | **computed in Chromium** - declared vs `getComputedStyle` at three viewports, `not-comparable` labelled per row |
284
+ | `data/design-audit.csv` | 0 | **computed in Chromium** - contrast, font fallback, CJK tracking, overflow, measure. Empty means it ran and found nothing |
285
+ | `data/data-class-hierarchy.csv` | 121 | source - every data class and its parent, so a type's inherited properties can be resolved |
232
286
  | `data/element-classes.csv` | 151 | **live** — the built-in class metas; their IDs are what an `elementClass` record must use |
233
287
  | `data/dynamic-variables.csv` | 74 | source — every `@VAR('ns/name')` expression, by namespace |
234
288
  | `data/evaluator-functions.csv` | 19 | source — the `@` functions with their arity |
@@ -320,6 +374,23 @@ post — `build_all.py` resets first for that reason.
320
374
  friends. A selector written against `div`/`nav` misses all of them.
321
375
  - **`icon` renders inline `<svg>`.**
322
376
 
377
+ ## Tools
378
+
379
+ | tool | does |
380
+ |---|---|
381
+ | `mo.py` | query the measured surface - **the front door** |
382
+ | `build_page.py` | commit one page spec through the verified write path |
383
+ | `build_site.py` | a whole site: one master with the shell, one document per page |
384
+ | `verify_rwd.py` | does every `_t`/`_m` declaration reach the served stylesheet? |
385
+ | `verify_browser.py` | does the **browser** compute what the stylesheet promised - and does the result pass a design audit? |
386
+ | `sweep_node_types.py` | commit every node type one per document and assert the delivered HTML |
387
+ | `sweep_style_properties.py` | write every style property and check the compiled CSS |
388
+ | `sweep_node_properties.py` | probe every node property with a value from its own validator chain |
389
+ | `theme_export.php` / `theme_import.php` | move a whole theme across installs, ids intact |
390
+ | `copy_styles.py` | push one node's style onto others, by attrID or prefix |
391
+ | `bootstrap_probe_theme.php` | a licence-free scratch theme |
392
+ | `mint_session.php` | a matching cookie + `wp_rest` nonce from WP-CLI |
393
+
323
394
  ## Regenerating everything
324
395
 
325
396
  ```bash
@@ -339,6 +410,7 @@ python tools/sweep_node_types.py --config sweep.json --setup
339
410
  python tools/sweep_node_types.py --config sweep.json --sweep --edition all
340
411
  python tools/sweep_properties.py --config sweep.json
341
412
  python tools/verify_rwd.py --config sweep.json --site sites/moksa.json --csv data/rwd-verification.csv
413
+ python tools/verify_browser.py --config sweep.json --site sites/moksa.json --csv data/browser-verification.csv --audit data/design-audit.csv
342
414
  python tools/sweep_style_properties.py --config sweep.json --page moksa --csv data/style-verification.csv
343
415
  python tools/sweep_node_properties.py --config sweep.json --page moksa --csv data/node-property-verification.csv
344
416
  wp eval-file tools/theme_export.php active > theme.json
@@ -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.2.1"
23
+ "version": "1.3.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.2.1"
23
+ "version": "1.3.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.2.1"
23
+ "version": "1.3.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.2.1"
23
+ "version": "1.3.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.2.1"
23
+ "version": "1.3.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,
@@ -79,6 +79,8 @@ const counts = {
79
79
  "data/style-verification.csv": 98,
80
80
  "data/node-property-verification.csv": 181,
81
81
  "data/rwd-verification.csv": 576,
82
+ "data/browser-verification.csv": 2237,
83
+ "data/data-class-hierarchy.csv": 121,
82
84
  };
83
85
  for (const [file, expected] of Object.entries(counts)) {
84
86
  if (!fs.existsSync(path.join(ROOT, file))) { fail(`${file} missing`); continue; }
@@ -94,6 +96,24 @@ const style = read("data/style-verification.csv");
94
96
  if (!style.includes("SKIPPED")) fail("style-verification.csv has no SKIPPED rows - "
95
97
  + "blind spots should be labelled, not dropped");
96
98
 
99
+ // The browser pass has the same obligation, under a different word: a declaration it
100
+ // cannot soundly compare must say so rather than be counted as agreement.
101
+ const browser = read("data/browser-verification.csv");
102
+ if (!browser.includes("not-comparable"))
103
+ fail("browser-verification.csv has no not-comparable rows - a computed-value check "
104
+ + "that claims to compare everything is comparing things it cannot");
105
+ if (browser.includes("OVERRIDDEN"))
106
+ fail("browser-verification.csv still contains OVERRIDDEN rows - the shipped example "
107
+ + "must render what it declares");
108
+
109
+ // The design audit ships even when it is empty, and empty has to mean "ran and found
110
+ // nothing" rather than "was never run", so the header alone is the proof.
111
+ const audit = read("data/design-audit.csv");
112
+ if (!audit.startsWith("url,breakpoints,check,level"))
113
+ fail("data/design-audit.csv is not the audit table verify_browser.py writes");
114
+ if (audit.includes(",error,"))
115
+ fail("data/design-audit.csv carries unresolved design errors");
116
+
97
117
  // ---------- nothing private ships -------------------------------------------
98
118
 
99
119
  // npm's `files` allowlist OVERRIDES .gitignore: naming a directory there ships