mosaic-headless 1.17.0 → 1.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -3,120 +3,271 @@
3
3
  [![npm downloads](https://img.shields.io/npm/dt/mosaic-headless?label=npm%20downloads&color=cb3837)](https://www.npmjs.com/package/mosaic-headless)
4
4
 
5
5
  [Mosaic Pro](https://mosaicbuilder.com)(Nextend)のサイトを、データモデルを直接書いて
6
- 構築・変更する — ビジュアルエディタも DOM も使わない。
6
+ 構築・変更する — ビジュアルエディタも DOM も使わない。Elementor のページを取り込む。
7
+ テーマをまるごと別のインストールへ移す。すべての主張は実際のサイトで計測済み。
7
8
 
8
9
  *他の言語:[English](README.md) · [繁體中文](README.zh-TW.md) · [한국어](README.ko.md)*
9
10
 
10
11
  ---
11
12
 
13
+ ## インストール
14
+
15
+ ```bash
16
+ npx mosaic-headless # 対話式:プラットフォームを選ぶ
17
+ npx mosaic-headless claude-code --global # Claude Code、~/.claude/skills/ へ
18
+ npx mosaic-headless cursor --to ./my-project
19
+ npx mosaic-headless --list # 対応 8 プラットフォーム
20
+ ```
21
+
22
+ | プラットフォーム | 何が入るか | どこに |
23
+ |---|---|---|
24
+ | Claude Code | スキル一式:SKILL.md + references/ + tools/ + data/ + sites/ | `~/.claude/skills/` または `./.claude/skills/` |
25
+ | Codex CLI | スキル一式 | `~/.codex/` |
26
+ | Gemini CLI | スキル一式 | `~/.gemini/` |
27
+ | GitHub Copilot | スキル一式に加え、`copilot-instructions.md` へ追記 | `./.github/` |
28
+ | Cursor | references を埋め込んだ `.mdc` ルール 1 本 | `~/.cursor/rules/` |
29
+ | Windsurf | references を埋め込んだルールファイル 1 本 | `./.devin/` |
30
+ | Continue | references を埋め込んだルールファイル 1 本 | `~/.continue/` |
31
+ | Claude.ai | プロジェクトスキルとしてアップロードする zip | 保存した場所 |
32
+
33
+ 各プラットフォームのインストールはリリースゲートがテンプレートに対して検証する。ツールの
34
+ 実行には Python 3 と Playwright が必要。ルールファイル型のプラットフォームには知識だけが
35
+ 入り、ツールは入らない。
36
+
37
+ **更新は自動では起きない。** npm に新版が出ても、エージェントが読み込むフォルダは変わらない。
38
+ インストーラを `--force` 付きで再実行する(付けないと、手を入れた可能性のある SKILL.md の
39
+ 上書きを拒否する):
40
+
41
+ ```bash
42
+ npx mosaic-headless@latest claude-code --global --force
43
+ ```
44
+
45
+
46
+ ## これは何か
47
+
12
48
  Mosaic はページを **23 個のカスタムテーブル**に保持する。`post_content` でもなければ
13
49
  `postmeta` でもない。要素ひとつにつき 1 行、ツリー構造は `parentID` カラム、兄弟の順序は
14
- fractional-index の文字列。エディタはこのモデルの一クライアントにすぎない。
15
- フォーマットそのものではないし、使う必要もない。
50
+ fractional-index の文字列。エディタはこのモデルの一クライアントにすぎない。フォーマット
51
+ そのものではないし、なくても困らない。
52
+
53
+ このスキルはそのモデルの地図 — ソースを読んで得たものではなく、実際のインストールに対して
54
+ 計測したもの — と、モデルを通して書き、出てきたものを検証し、Elementor からページを持ち込む
55
+ ためのツール群である。
56
+
57
+ ## 部品のつながり
58
+
59
+ ```mermaid
60
+ flowchart LR
61
+ subgraph measure["一度だけ、実サイトに対して計測"]
62
+ SRC[プラグインのソース] -->|extract_*.py| D[(data/*.csv)]
63
+ SW[sweep_*.py / probe_*.py] -->|commit・描画・断言| D
64
+ end
16
65
 
17
- この skill はそのモデルの地図であり、**ソースを読んだものではなく、実際のインストールに
18
- 対して測定したもの**である。
66
+ subgraph write["あなたが作るすべてのページ"]
67
+ Q[mo.py] -->|答えは一つ、計測結果が先頭| SPEC[ページ spec]
68
+ EL[Elementor _elementor_data] -->|from_elementor.py| SPEC
69
+ SPEC -->|build_page.py が壊れるものを拒否| REST[Mosaic REST:checkout・check・commit]
70
+ REST --> DB[(23 テーブル)]
71
+ DB --> PAGE[配信されたページ]
72
+ end
19
73
 
20
- ## すべてに優先するただ一つの規則
74
+ subgraph verify["commit を信用しない"]
75
+ PAGE --> V1[verify_rwd.py]
76
+ PAGE --> V2[verify_browser.py + デザイン監査]
77
+ PAGE --> V3[verify_intro.py / verify_loop.py]
78
+ PAGE --> V4[verify_conversion.py]
79
+ V1 & V2 & V3 & V4 --> CSV[(検証 CSV)]
80
+ CSV --> GATE[check-release.mjs]
81
+ end
21
82
 
22
- **ノードタイプ、プロパティ名、列挙値、スタイルキー、Free/Pro の判断を記憶で書かないこと。
23
- `data/` を引くこと。**
83
+ D --> Q
84
+ D --> SPEC
85
+ ```
86
+
87
+ 左から右へ:表は一度だけ計測して同梱される;すべてのページは表を通して書かれ、表が否と
88
+ 言えば拒否される;配信されたページを読み戻し、結果がリリースゲートの見る表に記録される
89
+ までは何も信用しない。
90
+
91
+ ## 唯一のルール
24
92
 
25
- しかも grep ではなく `mo.py` で引く。grep は打った質問には答えるが、本当に抱えている
26
- 質問には答えない。`accordion-content` を grep すればその型が存在することは分かる。
27
- スイープ表は BROKE_PAGE だと言う — 置けば公開ページ全体が 54 バイトのエラー文字列に
28
- なる。どちらも本当で、どちらも間違った答えだ。行の横の注記は、その文字列が「親がない」
29
- ことを名指ししていること、`accordion > accordion-item` の下に入れ子にすれば commit も
30
- 描画も通り、キーボードで操作できる開閉 UI までついてくることを言っている。
31
- `mo.py type` はその三つを一度に見せる。
93
+ **ノード型、プロパティ名、列挙値、スタイルキー、Free/Pro の判断を記憶から書かない。
94
+ `data/` で引く。**
95
+
96
+ しかも grep ではなく `mo.py` で引く。grep は打った質問には答えるが、本当に抱えている質問には
97
+ 答えない。`accordion-content` を grep すればその型が存在することは分かる。スイープ表は
98
+ BROKE_PAGE だと言う — 置けば公開ページ全体が 54 バイトのエラー文字列になる。どちらも本当で、
99
+ どちらも間違った答えだ。行の横の注記は、その文字列が「親がない」ことを名指ししていること、
100
+ `accordion > accordion-item` の下に入れ子にすれば commit も描画も通り、キーボードで操作できる
101
+ 開閉 UI までついてくることを言っている。`mo.py type` はその三つを一度に見せる。
32
102
 
33
103
  ```bash
34
104
  python tools/mo.py type accordion-content # 1 つの型を、全ライブスイープに接続して表示
35
- python tools/mo.py check div text button # 危険な型・未知の型があれば exit 1
36
- python tools/mo.py style --grouped # 単独設定では必ず効かない 20 個
37
- python tools/mo.py states --verified # 実測でコンパイルされた状態だけ
38
- python tools/mo.py params text # 1 つの型に設定できるものすべて
105
+ python tools/mo.py check div text button # 安全でない/未知の型があれば 1 で終了
106
+ python tools/mo.py params text # 1 つの型に設定できるすべて
107
+ python tools/mo.py style --grouped # 単独では無効になる 20 個
108
+ python tools/mo.py states --verified # コンパイルされることが計測済みの状態
109
+ python tools/mo.py css grid-column # この CSS を出す Mosaic のキー
39
110
  ```
40
111
 
41
- そのうえでページを見る。Mosaic の失敗の仕方は 4 通りあり、
42
- **HTTP ステータスが変わるのはそのうち 1 つだけ**:
112
+ そのうえでページを見る。Mosaic には **7 つ**の失敗モードがあり、HTTP ステータスが変わるのは
113
+ そのうち 2 つだけ:
43
114
 
44
115
  ```
45
- バリデータによる正常な拒否 HTTP 200 + body に exceptions 配列
46
- commit 中の PHP fatal HTTP 500 (122 タイプ中 15、素の div の中でも起きる)
47
- 構造的に不正なノード HTTP 200、コミット済み、DB に行もある。そして
48
- 公開ページ全体が 54 バイトのエラー文字列になる
49
- 値の「形」が違う HTTP 200、保存される。ただし CSS ルールが存在しない
50
- ルールは正しいが結果が違う HTTP 200、スタイルシートにあり、内容も正しい。それでも
51
- ブラウザは別の値を計算する
52
- URL に対応するテンプレなし HTTP 406、未ログインには空の body
116
+ バリデータの正常な拒否 HTTP 200 + 本文に `exceptions` 配列
117
+ commit 中の PHP fatal HTTP 500(122 型のうち 15 が plain div の下でこうなる)
118
+ 構造的に不正なノード HTTP 200、commit 済み、DB に行あり、そして公開ページ全体が
119
+ 54 バイトのエラー文字列になる
120
+ 値の「形」が違う HTTP 200、保存済み、CSS ルールがただ出ない
121
+ ルールは正しく結果が違う HTTP 200、スタイルシートにあり、正しく、ブラウザが別の値を計算する
122
+ URL にテンプレートがない HTTP 406、未ログインには空の本文
123
+ 内容による描画時 fatal HTTP 500 — commit は通り、Mosaic がページを解析する時に死ぬ。
124
+ `code` ノードの内容はテンプレートで、minifier が書く `@media(` は
125
+ 関数呼び出しとして読まれる。`@media (` なら描画される。
126
+ build_page は前者を拒否する。
53
127
  ```
54
128
 
55
- **commit の成功も、正しいスタイルシートも、ページが動いている証拠にはならない。**
129
+ commit の成功はページが動く証拠ではないし、正しいスタイルシートもそうではない。ここの
130
+ ツールはすべて書いた後にページを取得し、5xx を空ページとして扱う — WordPress の
131
+ 「重大なエラー」画面は 2,697 バイトで、素朴な「健全なページ」の下限より大きいからだ。
56
132
 
57
133
  ## 何を、どう検証したか
58
134
 
59
- すべて実際のインストール上で実行 — WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.7、
135
+ すべて実際のインストールに対して実行 — WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.7、
60
136
  **ライセンスなし**:ライセンスが制限するのはテーマライブラリと更新であってノードファクトリ
61
- ではないため、Pro のタイプも登録され描画される。
137
+ ではないので、Pro の型も登録・描画される。
62
138
 
63
- | 対象 | 結果 |
139
+ | 項目 | 結果 |
64
140
  |---|---|
65
- | **ノードタイプ** | 122 / 122。1 ドキュメントにつき 1 タイプで commit → 描画 → 断言 → 削除。70 RENDERED、30 COMMITTED、15 COMMIT_5xx、7 BROKE_PAGE |
141
+ | **ノード型** | 122 / 122 を 1 型 1 ドキュメントでスイープ、commit → 描画 → 断言 → 削除:70 RENDERED、30 COMMITTED、15 COMMIT_5xx、7 BROKE_PAGE。描画されなかった行のうち 3 つは「必要な親なしで commit した」というスイープ手法の産物で、その旨が行の横にある |
66
142
  | **スタイルプロパティ** | 98 / 98 を実ページに書き、コンパイル済み CSS と照合:58 COMPILED、18 ABSENT、21 SKIPPED |
67
- | **ノードプロパティ** | 181 / 181 を、各プロパティ自身の validator chain から導いた値で再測定:35 APPLIED、42 NO_EFFECT、55 NO_HOST、47 SKIPPED |
143
+ | **ノードプロパティ** | 181 / 181 を各プロパティ自身のバリデータ連鎖から導いた値で再探査:35 APPLIED、42 NO_EFFECT、55 NO_HOST、47 SKIPPED |
68
144
  | **レスポンシブ** | 2 サイト計 731 件の `_t`/`_m` 宣言を、サイトが実際に配信したスタイルシートに対して 1 件ずつ断言 — 全件検証済み |
69
- | **コンポーネント** | コンポーネント機構を端から端まで実行し **8 / 8**:カテゴリ配下に作成、ドキュメントを heal、書き込み可能な instance 経由でツリーを投入、読み取り専用の方は同じ書き込みを拒否(ネガティブコントロール)、最後に 2 つのインスタンスが 1 つの定義から描画 |
70
- | **スタイル状態** | 53 状態のうち 52 を実ページに書き、テーブルが約束するセレクタと照合:**36 件が完全一致**、12 件 NO_HOST、3 件 SKIPPED、1 件 BROKE_PAGE。どの要素にも使えるグローバル 7 状態はすべて検証済み |
71
- | **インタラクション** | JS アニメーション経路を、ネガティブコントロール付きで保存行を読み戻しながら検証:`propertyMetas` は**受理され保存される**。プロパティ値は依然としてバインドされないが、その境界は厳密になった |
72
- | **入場アニメーション** | 単調時計でページ読み込み後の 15 時点をサンプリングし 8 項目を断言 — 再生されること、アニメーションする `@property` カウンタが 100 に達すること、ベールがヒットテストから外れること、ビューポート内に opacity 0 のまま取り残された要素がないこと、実際のクリックが文書に届くこと、`prefers-reduced-motion` ではベールがそもそも存在しないこと、そして全てが落ち着いた後もなお動いているものがあること。文書の初回レイアウトを待ってから始まるため、アニメーションの全くないページに対して遅れフレームは 1 つだけ |
73
- | **常時アニメーション** | 隅で刷り続け、タップすると拡大する版 — **28 項目**:一時停止したタイムラインをスクラブして周期性を証明、5 つの幅 × 25 のスクロール位置でテキスト*と*操作要素の遮蔽を「決して読めない」を失敗条件として計測、ポインタでも Enter でも開くこと、reduced motion では静止すること。Mosaic 自身のアコーディオンの上に構築 |
74
- | **アコーディオン** | `accordion-item` と `accordion-content` はスイープ表では BROKE_PAGE。ファクトリが要求する通りに入れ子にすれば commit も描画も通る、**7 件中 7 件**。注記はその行の横にある |
75
145
  | **ブラウザ** | 配信された 2 ページを Chromium の 3 つのビューポートで計算スタイル 3,988 件読み取り:2,929 件が一致、912 件は比較不能として明示、**上書き 0 件** |
76
146
  | **デザイン監査** | コントラスト、フォントフォールバック、CJK の字送り、横溢れ、テキストの切れ、1 行の文字数 — ブラウザ上で実行、**指摘 26 件、すべて理由付きで裁定済み** — 理由のない容認はリリースゲートが拒否する |
77
- | **テーマの書き出し/読み込み** | 経路は二つ、どちらも往復検証済み。`theme_export.php` は WP-CLI で行を JSON として移し、id は不変、コピーはバイト単位で同一のページを配信。`theme_zip.py` は Mosaic **自身**の ZIP 書き出し/読み込みをそのマイルストーン・プロトコルで駆動する — 読み込みは `--activate` を付けない限りテストモードに入る、既定がライブサイトの切り替えだからだ — そして **22 項目**でコピーを元とツリー単位で突き合わせる:全テーブル一致、68,337 のノード id を保持、override ノードは再採番、足りない 1 行はツリー走査が運ぶべきでない孤児 |
78
- | **実測** | REST ルート 114、element class 151、条件サブジェクト 59、23 テーブル / 206 カラム |
147
+ | **コンポーネント** | コンポーネントシステムを端から端まで駆動、**8 件中 8 件**:カテゴリの下に作成、ドキュメントが自己修復、書き込み可能インスタンス経由でツリーを充填、読み取り専用インスタンスは同じ書き込みを拒否(ネガティブコントロール)、ページ上の 2 インスタンスが 1 つの定義を 2 度描画 |
148
+ | **スタイル状態** | 53 状態のうち 52 を実ページに書き、表が約束するセレクタと照合:**36 が完全一致**、12 NO_HOST、3 SKIPPED、1 BROKE_PAGE。擬似クラスは大文字で出力される(`.M_EL9:HOVER`) |
149
+ | **インタラクション** | JS アニメーション経路をネガティブコントロール付きで探査し行を読み戻し:`propertyMetas` **は**受理・保存される;プロパティ値は依然として結び付かず、その境界は正確になった |
150
+ | **アコーディオン** | `accordion-item` と `accordion-content` はスイープ表では BROKE_PAGE。ファクトリが要求する通りに入れ子にすれば commit も描画も通る、**7 件中 7 件** |
151
+ | **入場アニメーション** | 単調時計で 15 時点をサンプリングし 8 項目を断言。文書の初回レイアウトを待ってから始まるため、アニメーションの全くないページに対して遅れフレームは 1 つだけ |
152
+ | **常時アニメーション** | 隅で刷り続け、タップすると拡大する版 — **28 項目**:一時停止したタイムラインをスクラブして周期性を証明、5 つの幅 × 25 のスクロール位置でテキスト*と*操作要素の遮蔽を「決して読めない」を失敗条件として計測、ポインタでも Enter でも開く、reduced motion では静止 |
153
+ | **Elementor 変換** | 本番サイトの全 Elementor ページ — 19 ページ、3,292 要素 — を変換・構築し、元と照合:**19 件中 19 件**、3,281 要素を運び、11 要素を明示的に除外。さらに変換後ページをレスポンシブ・ブラウザ・監査にかけ、指摘をすべて「継承」か「導入」かに分類:**導入 0 件** |
154
+ | **テーマの書き出し/読み込み** | 経路は二つ、どちらも往復検証済み。`theme_export.php` は WP-CLI で行を JSON として移し、id は不変。`theme_zip.py` は Mosaic **自身**の ZIP 書き出し/読み込みを駆動 — 読み込みは `--activate` を付けない限りテストモードに入る、既定がライブサイトの切り替えだからだ — **22 項目**でコピーを元とツリー単位で突き合わせる |
155
+ | **スキル自身** | `claude plugin eval .` — ユーザーが実際に尋ねる 5 問を各 3 回、スキルあり/なしの 2 腕、1 回ごとに LLM 審査 3 名。**あり:5 問すべて 1.00。なし:5 問すべて 0.00。** ベースラインの最善の回答は回答拒否だった |
156
+ | **ライブ計測** | REST ルート 114、element class 151、条件サブジェクト 59、23 テーブル / 206 カラム |
157
+
158
+ `SKIPPED`、`NO_HOST`、`INCONCLUSIVE` は合格率に決して繰り込まない。自らの盲点を成功として
159
+ 数えるスイープこそ、このスキルが反対しているものだ。
79
160
 
80
- `SKIPPED`、`NO_HOST`、`INCONCLUSIVE` を合格率に混ぜることは決してしない。
81
- **自分の死角を成功として数えるスイープこそ、この skill が反対しているものである。**
161
+ ## 引くのに何トークンかかるか
82
162
 
83
- ### 書き始める前に知っておく価値のある 2 つの結果
163
+ Mosaic のノード型やスタイルキーが実際に何を受け取るかをエージェントが知る方法は三つ。
164
+ 同じ六つの課題を tiktoken で計測(`tools/benchmark_tokens.py`、自分で実行できる):
84
165
 
85
- **`group` を持つプロパティは、単独で設定しても効かない。** 両方向とも厳密:group を持たない
86
- 78 個は 58 COMPILED / 0 ABSENT、group を持つ 20 個はすべて 0 COMPILED。つまり
87
- `borderLeftWidth`、`outlineColor`、`gridColumnStart` は 3 つの別々の奇癖ではなく
88
- **同一の規則の 3 つの実例**である。グループ形状を使うか(`border` は
89
- `{width, style, color}` を取る)、`customStyles` に落とす。
166
+ | 課題 | ソースを読む | 全テーブル読込 | `mo.py` で引く |
167
+ |---|---:|---:|---:|
168
+ | 見出し・段落・リンク付きボタンを置く | 10,005 | 259,539 | **961** |
169
+ | padding・ボーダー・角丸をレスポンシブに設定 | 3,490 | 259,539 | **396** |
170
+ | アコーディオンが使えるか、どう入れ子にするか | 15,615 | 259,539 | **397** |
171
+ | 実際にコンパイルされる hover/focus 状態を探す | 3,619 | 259,539 | **1,054** |
172
+ | ある CSS を出す Mosaic のキーを探す | 1,862 | 259,539 | **51** |
173
+ | commit 前に何が危険かを知る | 63,172 | 259,539 | **288** |
174
+
175
+ **ソースを読むより 71〜99.5%、全テーブル読込より 99.6% 以上トークンが少ない** — しかも
176
+ 六つのうち四つはソースでは答えられない。「宣言されている」と「コンパイルされる」は別の
177
+ 問いで、後者を問うたのはスイープだけだからだ。テーブルは合計 259,539 トークン。決して
178
+ まとめて読み込まないこと。`mo.py` がクエリである。
179
+
180
+ ### 書く前に知っておくべき結果
181
+
182
+ **`group` に属するプロパティは単独で設定しても無効。** 両方向で厳密:グループ外の 78 個は
183
+ 58 COMPILED・0 ABSENT、グループ内の 20 個はすべて 0 COMPILED。`borderLeftWidth`、`outlineColor`、
184
+ `gridColumnStart` は一つのルールの三つの例。グループの形 — `border` は `{width, style, color}` —
185
+ か `customStyles` を使う。
90
186
 
91
187
  **ブレークポイントの上書きはプロパティを「変える」ことはできても「消す」ことはできない。**
92
- 狭い画面の `customStyles` が単に境界線を書いていないだけなら、広い画面の境界線は生き残り、
93
- 1 カラムに畳まれたレイアウトの真ん中に線を引く。**`border-left:0` と明示すること。**
188
+ 狭い画面の `customStyles` が単にボーダーを書かないだけなら、広い画面のボーダーは立ったままだ。
189
+ `border-left:0` と声に出す。
94
190
 
95
- ## ツール
191
+ **`url` を受け取る型は 4 つだけ**:`button`、`menu-link`、`wysiwyg-link`、`dropdown-toggle`。
192
+ `text` や `image` に置くと、受理され、保存され、アンカーは一切出ない。代わりに `menu-link` で
193
+ 包む — 任意の子を取り、`url` があれば本物の `<a href>` になる。
194
+
195
+ **画像の attachment protocol のパスは uploads ディレクトリからの相対。**
196
+ `wp-attachment://image/<id>/full/2026/09/pic.png` は解決され、添付の幅と高さも乗る。フルパスの
197
+ `wp-content/uploads/...` を渡すと — 一番自然な推測だが — Mosaic は uploads のベースをもう一度
198
+ 前置し、しかもエラーを出さない。
199
+
200
+ ## Elementor → Mosaic
96
201
 
97
202
  ```bash
98
- wp eval-file tools/bootstrap_probe_theme.php # ライセンス不要の作業用テーマ
99
- python tools/build_site.py --config c.json --site sites/moksa.json
100
- python tools/verify_rwd.py --config c.json --site sites/moksa.json --csv rwd.csv
101
- python tools/copy_styles.py --config c.json --from a --to-prefix b- --only "&._m"
102
- wp eval-file tools/theme_export.php active > theme.json
103
- wp eval-file tools/theme_import.php theme.json "名前" rebind activate
203
+ wp post meta get 2360 _elementor_data > page.json
204
+ python tools/from_elementor.py --data page.json --out spec.json --report conv.csv \
205
+ --uploads-base https://site/wp-content/uploads --slug works --post 208
206
+ python tools/build_site.py --config c.json --site spec.json
207
+ python tools/verify_conversion.py --data page.json --url https://site/works/ --report conv.csv
104
208
  ```
105
209
 
106
- `sites/_moksa.py` が完全な実例:実在するスタジオのトップページ — マストヘッド、仕様ブロック、
107
- サービス、9 行の実績テーブル、プロセス、技術スタック、プロダクト、推薦の声、連絡先 —
108
- **618 ノードをすべてテーブル経由で commit**。名前付き view timeline で作った、スクロールに
109
- 追随する条項インデックスも含め、JavaScript は一切使っていない。
210
+ 対象範囲は好みではなく数えて決めた:実サイト 19 ページのうち、container / heading /
211
+ text-editor / button / html / icon-list / divider / image で全要素の 99.6%。ロングテール —
212
+ loop grid、フォーム、カウントダウン、サードパーティ addon — は動的で、なるべきノードがない。
213
+ それぞれ名前と理由付きで報告され、黙って落とされることはなく、`--strict` は損失のある spec の
214
+ 出力を拒否する。
215
+
216
+ レイアウト、タイポグラフィ、色、ボーダー、リンク、画像は 3 つのブレークポイントすべてで移る
217
+ (`_tablet`/`_mobile` → `_t`/`_m`)。移らないもの:入場アニメーション(Mosaic のインタラクション
218
+ 結合は未解決)、shape divider、グラデーションオーバーレイ。検証ツールは構築後のページを元と
219
+ 突き合わせ — 文字列、画像、リンク、見出しレベルをすべて — 初回から役に立った:`url` を無視する
220
+ ノードに書いていたせいで 21 リンク中 19 を落としていた変換器を捕まえた。
110
221
 
111
- ## どこから読むか
222
+ ## ツール
223
+
224
+ | ツール | 役割 |
225
+ |---|---|
226
+ | `mo.py` | 計測済みの表面を引く — **正面玄関** |
227
+ | `build_page.py` / `build_site.py` | ガード付きの書き込み経路で spec を commit;壊れると計測されたものは拒否 |
228
+ | `from_elementor.py` / `verify_conversion.py` | Elementor → Mosaic と、内容が届いたことの証明 |
229
+ | `verify_browser.py` | ブラウザがスタイルシートの約束通りに計算したか、デザイン監査に通るか |
230
+ | `verify_rwd.py` | すべての `_t`/`_m` 宣言が配信スタイルシートに届いているか |
231
+ | `verify_intro.py` / `verify_loop.py` | 「終わる」ロードアニメーション;ループし、何も隠さず、開く常時アニメーション |
232
+ | `theme_export.php` / `theme_import.php` | テーマ全体を JSON 行として WP-CLI で移動、id は不変 |
233
+ | `theme_zip.py` / `theme_zip_compare.php` / `theme_delete.php` | Mosaic 自身の ZIP 書き出し/読み込みをエディタの外から駆動、コピーを元とツリー単位で照合、ライブテーマを拒否する完全削除 |
234
+ | `sweep_*.py` / `probe_*.py` | 表を作った計測器そのもの |
235
+ | `bootstrap_probe_theme.php` / `mint_session.php` | ライセンス不要の実験用テーマと、WP-CLI から作る REST セッション |
112
236
 
113
- 1. `references/data-model.md` — ページが実際にどこにあるか。
237
+ ## 実例
238
+
239
+ `sites/_moksa.py` はテーブルだけで本物のスタジオサイトを構築し、参照実装として同梱される:
240
+ 1,286 ノードのホームページに、名前付き view timeline によるスクロール追従の条項インデックス;
241
+ 浮世絵の版を一枚ずつ刷っていく入場シーケンス;隅で永遠に刷り続け、タップで拡大する版;
242
+ そして UI 全体が shortcode を実行する 1 つの `code` ノードから届く WooCommerce の My Account
243
+ ページ。自前の JavaScript はどこにもない。`data/` のすべての検証表はこれに対して作られた。
244
+
245
+ ## どこから始めるか
246
+
247
+ 1. `references/data-model.md` — ページが実際に住んでいる場所。
114
248
  2. `references/write-protocol.md` — checkout / check / commit。
115
- 3. `references/failure-modes.md` — Mosaic の壊れ方、すべて実測。**書く前に読む。**
116
- 4. `references/responsive.md` — state / breakpoint / property という軸。
249
+ 3. `references/failure-modes.md` — Mosaic の失敗のしかた、計測版。**書く前に読む。**
250
+ 4. `references/responsive.md` — 状態/ブレークポイント/プロパティの軸。
117
251
  5. `references/styling.md` — スタイル値が CSS になるまで。
118
252
  6. `references/design-system.md` — element class とデザイントークン。
119
253
 
254
+ ## リリース
255
+
256
+ ```bash
257
+ npm version minor # package.json、SKILL.md、8 つのプラットフォームテンプレートの版を上げ、
258
+ # commit、tag、push;tag が release.yml を起動する
259
+ ```
260
+
261
+ `bin/check-release.mjs` がすべてのリリースを門番する。検査するのは「検査しやすいこと」ではなく
262
+ 「間違えやすいこと」:版番号の一致、`files` の各 glob が何かに一致すること、各検証 CSV の行数が
263
+ SKILL.md と 4 つの README が引用する数と等しいこと、未裁定のデザイン監査指摘がないこと、eval
264
+ スイートが存在すること、そして **tarball そのものの検査** — npm の `files` 許可リストは
265
+ `.gitignore` を上書きし、かつて本物のクライアントのサイトを公開直前のパッケージに入れかけた。
266
+
267
+ 公開は npm の trusted publishing(OIDC):トークンはどこにもない。npmjs.com のパッケージ設定
268
+ Trusted Publisher にて:GitHub Actions、`Moksa1123` / `mosaic-headless`、workflow `release.yml`、
269
+ environment は**空**。
270
+
120
271
  ## ライセンス
121
272
 
122
- MIT。Mosaic Pro 自体はライセンス製品であり、この repo に**含まれていない**。
273
+ MIT。Mosaic Pro 自体はライセンスされたサードパーティ製ソフトウェアで、ここには**含まれない**。