mosaic-headless 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +94 -0
  3. package/README.md +133 -0
  4. package/README.zh-CN.md +87 -0
  5. package/README.zh-TW.md +87 -0
  6. package/SKILL.md +353 -0
  7. package/assets/templates/platforms/claude-ai.json +34 -0
  8. package/assets/templates/platforms/claude-code.json +28 -0
  9. package/assets/templates/platforms/codex-cli.json +33 -0
  10. package/assets/templates/platforms/continue.json +31 -0
  11. package/assets/templates/platforms/copilot.json +46 -0
  12. package/assets/templates/platforms/cursor.json +36 -0
  13. package/assets/templates/platforms/gemini-cli.json +33 -0
  14. package/assets/templates/platforms/windsurf.json +34 -0
  15. package/bin/check-release.mjs +143 -0
  16. package/bin/install.mjs +452 -0
  17. package/bin/sync-version.mjs +63 -0
  18. package/data/animatable-properties.csv +23 -0
  19. package/data/condition-comparators.csv +13 -0
  20. package/data/condition-subjects.csv +60 -0
  21. package/data/db-columns.csv +207 -0
  22. package/data/default-children.csv +11 -0
  23. package/data/dynamic-variables.csv +75 -0
  24. package/data/element-classes.csv +152 -0
  25. package/data/evaluator-functions.csv +20 -0
  26. package/data/interaction-types.csv +13 -0
  27. package/data/node-properties.csv +182 -0
  28. package/data/node-property-verification.csv +182 -0
  29. package/data/node-types.csv +123 -0
  30. package/data/node-verification.csv +123 -0
  31. package/data/placement-rules.csv +123 -0
  32. package/data/pluggables.csv +208 -0
  33. package/data/property-verification.csv +171 -0
  34. package/data/rest-routes.csv +115 -0
  35. package/data/rwd-verification.csv +570 -0
  36. package/data/style-properties.csv +99 -0
  37. package/data/style-states.csv +54 -0
  38. package/data/style-value-shapes.csv +23 -0
  39. package/data/style-verification.csv +99 -0
  40. package/package.json +59 -0
  41. package/references/data-model.md +95 -0
  42. package/references/design-system.md +118 -0
  43. package/references/dynamic-content.md +113 -0
  44. package/references/failure-modes.md +182 -0
  45. package/references/interactions.md +126 -0
  46. package/references/placement.md +117 -0
  47. package/references/responsive.md +174 -0
  48. package/references/styling.md +172 -0
  49. package/references/templates-and-conditions.md +122 -0
  50. package/references/vs-elementor-gutenberg.md +73 -0
  51. package/references/write-protocol.md +79 -0
  52. package/sites/_moksa.py +1165 -0
  53. package/sites/moksa.json +8685 -0
  54. package/tools/bootstrap_probe_theme.php +68 -0
  55. package/tools/build_all.py +55 -0
  56. package/tools/build_page.py +352 -0
  57. package/tools/build_report.py +221 -0
  58. package/tools/build_site.py +174 -0
  59. package/tools/capture_live.py +130 -0
  60. package/tools/check_placement_predicts.py +72 -0
  61. package/tools/copy_styles.py +204 -0
  62. package/tools/extract_default_children.py +94 -0
  63. package/tools/extract_dynamic_variables.py +104 -0
  64. package/tools/extract_interactions.py +98 -0
  65. package/tools/extract_node_types.py +165 -0
  66. package/tools/extract_placement.py +135 -0
  67. package/tools/extract_pluggables.py +90 -0
  68. package/tools/extract_style_properties.py +163 -0
  69. package/tools/mint_session.php +52 -0
  70. package/tools/probe.py +144 -0
  71. package/tools/sweep_node_properties.py +271 -0
  72. package/tools/sweep_node_types.py +318 -0
  73. package/tools/sweep_properties.py +215 -0
  74. package/tools/sweep_style_properties.py +254 -0
  75. package/tools/theme_export.php +91 -0
  76. package/tools/theme_import.php +113 -0
  77. package/tools/verify_rwd.py +278 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 moksa (https://moksaweb.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ja.md ADDED
@@ -0,0 +1,94 @@
1
+ # mosaic-headless
2
+
3
+ [Mosaic Pro](https://mosaicbuilder.com)(Nextend)のサイトを、データモデルを直接書いて
4
+ 構築・変更する — ビジュアルエディタも DOM も使わない。
5
+
6
+ *他の言語:[English](README.md) · [繁體中文](README.zh-TW.md) · [简体中文](README.zh-CN.md)*
7
+
8
+ ---
9
+
10
+ Mosaic はページを **23 個のカスタムテーブル**に保持する。`post_content` でもなければ
11
+ `postmeta` でもない。要素ひとつにつき 1 行、ツリー構造は `parentID` カラム、兄弟の順序は
12
+ fractional-index の文字列。エディタはこのモデルの一クライアントにすぎない。
13
+ フォーマットそのものではないし、使う必要もない。
14
+
15
+ この skill はそのモデルの地図であり、**ソースを読んだものではなく、実際のインストールに
16
+ 対して測定したもの**である。
17
+
18
+ ## すべてに優先するただ一つの規則
19
+
20
+ **ノードタイプ、プロパティ名、列挙値、スタイルキー、Free/Pro の判断を記憶で書かないこと。
21
+ `data/` を引くこと。**
22
+
23
+ そのうえでページを見る。Mosaic の失敗の仕方は 4 通りあり、
24
+ **HTTP ステータスが変わるのはそのうち 1 つだけ**:
25
+
26
+ ```
27
+ バリデータによる正常な拒否 HTTP 200 + body に exceptions 配列
28
+ commit 中の PHP fatal HTTP 500 (122 タイプ中 15、素の div の中でも起きる)
29
+ 構造的に不正なノード HTTP 200、コミット済み、DB に行もある。そして
30
+ 公開ページ全体が 54 バイトのエラー文字列になる
31
+ 値の「形」が違う HTTP 200、保存される。ただし CSS ルールが存在しない
32
+ URL に対応するテンプレなし HTTP 406、未ログインには空の body
33
+ ```
34
+
35
+ **commit の成功は、ページが動いている証拠にはならない。**
36
+
37
+ ## 何を、どう検証したか
38
+
39
+ すべて実際のインストール上で実行 — WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.7、
40
+ **ライセンスなし**:ライセンスが制限するのはテーマライブラリと更新であってノードファクトリ
41
+ ではないため、Pro のタイプも登録され描画される。
42
+
43
+ | 対象 | 結果 |
44
+ |---|---|
45
+ | **ノードタイプ** | 122 / 122。1 ドキュメントにつき 1 タイプで commit → 描画 → 断言 → 削除。70 RENDERED、30 COMMITTED、15 COMMIT_5xx、7 BROKE_PAGE |
46
+ | **スタイルプロパティ** | 98 / 98 を実ページに書き、コンパイル済み CSS と照合:58 COMPILED、18 ABSENT、21 SKIPPED |
47
+ | **ノードプロパティ** | 181 / 181 を、各プロパティ自身の validator chain から導いた値で再測定:35 APPLIED、42 NO_EFFECT、55 NO_HOST、47 SKIPPED |
48
+ | **レスポンシブ** | 2 サイト計 569 件の `_t`/`_m` 宣言を、サイトが実際に配信したスタイルシートに対して 1 件ずつ断言 — 全件検証済み |
49
+ | **テーマの書き出し/読み込み** | 往復検証済み:テーマ全体を書き出し、コピーとして読み込み、そのコピーがバイト単位で同一のページを配信 |
50
+ | **実測** | REST ルート 114、element class 151、条件サブジェクト 59、23 テーブル / 206 カラム |
51
+
52
+ `SKIPPED`、`NO_HOST`、`INCONCLUSIVE` を合格率に混ぜることは決してしない。
53
+ **自分の死角を成功として数えるスイープこそ、この skill が反対しているものである。**
54
+
55
+ ### 書き始める前に知っておく価値のある 2 つの結果
56
+
57
+ **`group` を持つプロパティは、単独で設定しても効かない。** 両方向とも厳密:group を持たない
58
+ 78 個は 58 COMPILED / 0 ABSENT、group を持つ 20 個はすべて 0 COMPILED。つまり
59
+ `borderLeftWidth`、`outlineColor`、`gridColumnStart` は 3 つの別々の奇癖ではなく
60
+ **同一の規則の 3 つの実例**である。グループ形状を使うか(`border` は
61
+ `{width, style, color}` を取る)、`customStyles` に落とす。
62
+
63
+ **ブレークポイントの上書きはプロパティを「変える」ことはできても「消す」ことはできない。**
64
+ 狭い画面の `customStyles` が単に境界線を書いていないだけなら、広い画面の境界線は生き残り、
65
+ 1 カラムに畳まれたレイアウトの真ん中に線を引く。**`border-left:0` と明示すること。**
66
+
67
+ ## ツール
68
+
69
+ ```bash
70
+ wp eval-file tools/bootstrap_probe_theme.php # ライセンス不要の作業用テーマ
71
+ python tools/build_site.py --config c.json --site sites/moksa.json
72
+ python tools/verify_rwd.py --config c.json --site sites/moksa.json --csv rwd.csv
73
+ python tools/copy_styles.py --config c.json --from a --to-prefix b- --only "&._m"
74
+ wp eval-file tools/theme_export.php active > theme.json
75
+ wp eval-file tools/theme_import.php theme.json "名前" rebind activate
76
+ ```
77
+
78
+ `sites/_moksa.py` が完全な実例:実在するスタジオのトップページ — マストヘッド、仕様ブロック、
79
+ サービス、9 行の実績テーブル、プロセス、技術スタック、プロダクト、推薦の声、連絡先 —
80
+ **590 ノードをすべてテーブル経由で commit**。名前付き view timeline で作った、スクロールに
81
+ 追随する条項インデックスも含め、JavaScript は一切使っていない。
82
+
83
+ ## どこから読むか
84
+
85
+ 1. `references/data-model.md` — ページが実際にどこにあるか。
86
+ 2. `references/write-protocol.md` — checkout / check / commit。
87
+ 3. `references/failure-modes.md` — Mosaic の壊れ方、すべて実測。**書く前に読む。**
88
+ 4. `references/responsive.md` — state / breakpoint / property という軸。
89
+ 5. `references/styling.md` — スタイル値が CSS になるまで。
90
+ 6. `references/design-system.md` — element class とデザイントークン。
91
+
92
+ ## ライセンス
93
+
94
+ MIT。Mosaic Pro 自体はライセンス製品であり、この repo に**含まれていない**。
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # mosaic-headless
2
+
3
+ Build and modify [Mosaic Pro](https://mosaicbuilder.com) (Nextend) sites by writing
4
+ the data model directly — no visual editor, no DOM.
5
+
6
+ *Read this in [繁體中文](README.zh-TW.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)*
7
+
8
+ ---
9
+
10
+ Mosaic keeps a page in **23 custom database tables**, not in `post_content` and not
11
+ in `postmeta`. One row per element, the tree carried by a `parentID` column, sibling
12
+ order by a fractional-index string. The editor is one client of that model. It is not
13
+ the format, and you do not need it.
14
+
15
+ This skill is the map of that model — measured against a live install rather than
16
+ read off the source.
17
+
18
+ ## The one rule
19
+
20
+ **Never write a node type, property name, enum value, style key or Free/Pro claim
21
+ from memory. Look it up in `data/`.**
22
+
23
+ Then check the page. Mosaic has four failure modes and **only one of them changes the
24
+ HTTP status code**:
25
+
26
+ ```
27
+ clean validator rejection HTTP 200 + an `exceptions` array in the body
28
+ PHP fatal during commit HTTP 500 (15 of 122 types do this from a plain div)
29
+ structurally invalid node HTTP 200, committed, row in the DB, and the whole
30
+ public page becomes a 54-byte error string
31
+ wrong value SHAPE HTTP 200, stored, and the CSS rule is simply absent
32
+ no template for the URL HTTP 406 with an EMPTY BODY for anyone not logged in
33
+ ```
34
+
35
+ A successful commit is not evidence of a working page.
36
+
37
+ ## What was verified, and how
38
+
39
+ Everything ran against a live install — WordPress 7.1, WooCommerce 11.1, Mosaic Pro
40
+ 1.0.7, **unlicensed**: the licence gates the theme library and updates, not the node
41
+ factories, so Pro types register and render regardless.
42
+
43
+ | pass | result |
44
+ |---|---|
45
+ | **node types** | 122 / 122 swept one per document, committed → rendered → asserted → deleted: 70 RENDERED, 30 COMMITTED, 15 COMMIT_5xx, 7 BROKE_PAGE |
46
+ | **style properties** | 98 / 98 written to a live page and checked against the compiled CSS: 58 COMPILED, 18 ABSENT, 21 SKIPPED |
47
+ | **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
+ | **responsive** | 569 `_t`/`_m` declarations across two sites asserted against the stylesheet the site actually served — all verified |
49
+ | **theme export/import** | round-tripped: a full theme exported, re-imported as a copy, and the copy served byte-identical pages |
50
+ | **measured live** | 114 REST routes, 151 element classes, 59 condition subjects, 23 tables / 206 columns |
51
+
52
+ `SKIPPED`, `NO_HOST` and `INCONCLUSIVE` are never folded into a pass rate. A sweep
53
+ that scores its own blind spots as successes is the thing this skill argues against.
54
+
55
+ ### Two results worth knowing before you write anything
56
+
57
+ **A property that belongs to a `group` is inert when set on its own.** Exact in both
58
+ directions: 78 ungrouped properties gave 58 COMPILED and 0 ABSENT; all 20 grouped
59
+ ones gave 0 COMPILED. So `borderLeftWidth`, `outlineColor` and `gridColumnStart` are
60
+ three instances of one rule, not three oddities. Use the grouped shape — `border`
61
+ takes `{width, style, color}` — or `customStyles`.
62
+
63
+ **A breakpoint override can CHANGE a property but never REMOVE one.** Narrow-screen
64
+ `customStyles` that merely omits a border leaves the wide-screen border standing,
65
+ drawing rules down the middle of a collapsed layout. Say `border-left:0` out loud.
66
+
67
+ ## Tools
68
+
69
+ ```bash
70
+ wp eval-file tools/bootstrap_probe_theme.php # licence-free scratch theme
71
+ python tools/build_site.py --config c.json --site sites/moksa.json
72
+ python tools/verify_rwd.py --config c.json --site sites/moksa.json --csv rwd.csv
73
+ python tools/copy_styles.py --config c.json --from a --to-prefix b- --only "&._m"
74
+ wp eval-file tools/theme_export.php active > theme.json
75
+ wp eval-file tools/theme_import.php theme.json "Name" rebind activate
76
+ ```
77
+
78
+ `sites/_moksa.py` is the worked example: a real studio homepage — masthead, spec
79
+ block, services, a nine-row work table, process, stack, products, testimonials,
80
+ contact — 590 nodes committed entirely through the tables, with a scroll-tracking
81
+ clause index built on named view timelines and no JavaScript.
82
+
83
+ ## Where to start
84
+
85
+ 1. `references/data-model.md` — where a page actually lives.
86
+ 2. `references/write-protocol.md` — checkout / check / commit.
87
+ 3. `references/failure-modes.md` — how Mosaic fails, measured. **Read before writing.**
88
+ 4. `references/responsive.md` — the state/breakpoint/property axis.
89
+ 5. `references/styling.md` — how a style value becomes CSS.
90
+ 6. `references/design-system.md` — element classes and design tokens.
91
+
92
+ ## Releasing
93
+
94
+ One command. The version lives in three places — `package.json`, the SKILL.md
95
+ frontmatter an agent reads, and the frontmatter each platform template writes on
96
+ install — and nothing keeps them together on its own.
97
+
98
+ ```bash
99
+ npm version patch # or minor / major
100
+ ```
101
+
102
+ That runs, in order:
103
+
104
+ 1. `preversion` → `bin/check-release.mjs`
105
+ 2. npm bumps `package.json`
106
+ 3. `version` → `bin/sync-version.mjs` writes the new number into SKILL.md and all
107
+ eight platform templates, and stages them
108
+ 4. npm commits and tags `vX.Y.Z`
109
+ 5. `postversion` → pushes the commit and the tag
110
+
111
+ The tag push triggers `.github/workflows/release.yml`, which refuses to publish
112
+ unless the tag matches `package.json`, re-runs the release checks, proves the
113
+ installer runs, prints the tarball, then publishes with provenance and opens a
114
+ GitHub release.
115
+
116
+ `bin/check-release.mjs` is the gate, and it checks the things that are easy to get
117
+ wrong rather than the things that are easy to check:
118
+
119
+ - the three version numbers agree
120
+ - every glob in `files` matches something
121
+ - the row counts in the verification CSVs still equal the numbers SKILL.md quotes
122
+ - `SKIPPED` labels survive into the shipped data, because a sweep that hides its
123
+ blind spots is the failure this skill argues against
124
+ - **the tarball itself is inspected**, not the intent. npm's `files` allowlist
125
+ *overrides* `.gitignore`: naming a directory ships everything inside it, ignored
126
+ or not. Listing `sites/` once put a real client's generator and content into the
127
+ tarball — gitignored, and about to be published anyway.
128
+
129
+ One-time setup: add the `NPM_TOKEN` repository secret.
130
+
131
+ ## Licence
132
+
133
+ MIT. Mosaic Pro itself is licensed third-party software and is **not** included here.
@@ -0,0 +1,87 @@
1
+ # mosaic-headless
2
+
3
+ 直接写入数据模型来构建和修改 [Mosaic Pro](https://mosaicbuilder.com)(Nextend)网站——
4
+ 不开可视化编辑器,不碰 DOM。
5
+
6
+ *其他语言:[English](README.md) · [繁體中文](README.zh-TW.md) · [日本語](README.ja.md)*
7
+
8
+ ---
9
+
10
+ Mosaic 把一个页面放在 **23 张自定义数据表**里,不在 `post_content`,也不在 `postmeta`。
11
+ 一个元素一行,树状结构靠 `parentID` 字段,同层顺序是一个 fractional-index 字符串。
12
+ 编辑器只是这个模型的一个客户端。它不是格式本身,你也不需要它。
13
+
14
+ 这个 skill 就是那个模型的地图——**对着真实安装量出来的,不是从源码读出来的**。
15
+
16
+ ## 唯一一条凌驾一切的规则
17
+
18
+ **绝不凭印象写节点类型、属性名、枚举值、样式键或 Free/Pro 的判断。去 `data/` 里查。**
19
+
20
+ 然后去看页面。Mosaic 有四种失效模式,**其中只有一种会改变 HTTP 状态码**:
21
+
22
+ ```
23
+ 校验器干净地拒绝 HTTP 200 + body 里一个 exceptions 数组
24
+ commit 时 PHP fatal HTTP 500 (122 种类型里有 15 种,光放在 div 里就会)
25
+ 结构无效的节点 HTTP 200、已写入、数据库有那一行,然后整个公开页面
26
+ 变成一段 54 字节的错误字符串
27
+ 值的「形状」错误 HTTP 200、已保存,而那条 CSS 规则就是不存在
28
+ 该网址没有对应模板 HTTP 406,且对未登录者是空白 body
29
+ ```
30
+
31
+ **commit 成功不能当作页面正常的证据。**
32
+
33
+ ## 验证了什么,怎么验的
34
+
35
+ 全部跑在真实安装上——WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.7、**未授权**:
36
+ 授权管的是主题库和更新,不是节点工厂,所以 Pro 类型照样注册、照样渲染。
37
+
38
+ | 项目 | 结果 |
39
+ |---|---|
40
+ | **节点类型** | 122 / 122,一份文档一种类型:写入 → 渲染 → 断言 → 删除。70 RENDERED、30 COMMITTED、15 COMMIT_5xx、7 BROKE_PAGE |
41
+ | **样式属性** | 98 / 98 写进真实页面并对照编译后的 CSS:58 COMPILED、18 ABSENT、21 SKIPPED |
42
+ | **节点属性** | 181 / 181,用每个属性自己的 validator chain 推导出的值重测:35 APPLIED、42 NO_EFFECT、55 NO_HOST、47 SKIPPED |
43
+ | **响应式** | 两个站共 569 条 `_t`/`_m` 声明,对照网站实际送出的样式表逐条断言——全部通过 |
44
+ | **主题导出/导入** | 完整往返验证:导出整个主题、以副本身份导入,副本送出的页面逐字节相同 |
45
+ | **线上量测** | 114 条 REST 路由、151 个 element class、59 个条件主体、23 张表 / 206 个字段 |
46
+
47
+ `SKIPPED`、`NO_HOST`、`INCONCLUSIVE` 永远不并入通过率。
48
+ **一个把自己的盲点算成成功的扫描工具,正是这个 skill 要反对的东西。**
49
+
50
+ ### 动手之前值得先知道的两个结果
51
+
52
+ **带有 `group` 的属性,单独设置一律无效。** 两个方向都精确:78 个无 group 的属性得到
53
+ 58 COMPILED、0 ABSENT;20 个有 group 的全部 0 COMPILED。所以 `borderLeftWidth`、
54
+ `outlineColor`、`gridColumnStart` 是**同一条规则的三个实例**,不是三个各自的怪毛病。
55
+ 要用就用分组形状——`border` 收 `{width, style, color}`——或者退回 `customStyles`。
56
+
57
+ **断点覆盖只能「改变」属性,永远不能「移除」。** 窄屏的 `customStyles` 如果只是
58
+ 没写某条边框,宽屏那条边框会活下来,在塌成单列的版面正中间画一条线。
59
+ **要把 `border-left:0` 明确写出来。**
60
+
61
+ ## 工具
62
+
63
+ ```bash
64
+ wp eval-file tools/bootstrap_probe_theme.php # 免授权的测试主题
65
+ python tools/build_site.py --config c.json --site sites/moksa.json
66
+ python tools/verify_rwd.py --config c.json --site sites/moksa.json --csv rwd.csv
67
+ python tools/copy_styles.py --config c.json --from a --to-prefix b- --only "&._m"
68
+ wp eval-file tools/theme_export.php active > theme.json
69
+ wp eval-file tools/theme_import.php theme.json "名称" rebind activate
70
+ ```
71
+
72
+ `sites/_moksa.py` 是完整示例:一个真实工作室的首页——报头、规格区块、服务、九行作品表格、
73
+ 流程、技术栈、产品、客户评价、联系——**590 个节点全部通过数据表写入**,
74
+ 还有一个用具名 view timeline 做的、会跟随滚动的条款索引,完全没有 JavaScript。
75
+
76
+ ## 从哪里开始读
77
+
78
+ 1. `references/data-model.md` —— 页面到底住在哪里。
79
+ 2. `references/write-protocol.md` —— checkout / check / commit。
80
+ 3. `references/failure-modes.md` —— Mosaic 怎么坏的,都是量出来的。**动笔前先读。**
81
+ 4. `references/responsive.md` —— state / breakpoint / property 这个轴。
82
+ 5. `references/styling.md` —— 一个样式值怎么变成 CSS。
83
+ 6. `references/design-system.md` —— element class 与设计 token。
84
+
85
+ ## 许可
86
+
87
+ MIT。Mosaic Pro 本身是有授权的第三方软件,**不包含**在这个 repo 里。
@@ -0,0 +1,87 @@
1
+ # mosaic-headless
2
+
3
+ 直接寫入資料模型來建置與修改 [Mosaic Pro](https://mosaicbuilder.com)(Nextend)網站——
4
+ 不開視覺編輯器,不碰 DOM。
5
+
6
+ *其他語言:[English](README.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)*
7
+
8
+ ---
9
+
10
+ Mosaic 把一個頁面放在 **23 張自訂資料表**裡,不在 `post_content`,也不在 `postmeta`。
11
+ 一個元素一列,樹狀結構靠 `parentID` 欄位,同層順序是一個 fractional-index 字串。
12
+ 編輯器只是這個模型的其中一個客戶端。它不是格式本身,而且你不需要它。
13
+
14
+ 這個 skill 就是那個模型的地圖——**對著真實安裝量出來的,不是從原始碼讀出來的**。
15
+
16
+ ## 唯一一條凌駕一切的規則
17
+
18
+ **絕不憑印象寫節點型別、屬性名稱、列舉值、樣式鍵或 Free/Pro 的判斷。到 `data/` 裡查。**
19
+
20
+ 然後去看頁面。Mosaic 有四種失效模式,**其中只有一種會改變 HTTP 狀態碼**:
21
+
22
+ ```
23
+ 驗證器乾淨地拒絕 HTTP 200 + body 裡一個 exceptions 陣列
24
+ commit 時 PHP fatal HTTP 500 (122 種型別裡有 15 種,光放在 div 裡就會)
25
+ 結構無效的節點 HTTP 200、已寫入、資料庫有那一列,然後整個公開頁面
26
+ 變成一段 54 bytes 的錯誤字串
27
+ 值的「形狀」錯誤 HTTP 200、已儲存,而那條 CSS 規則就是不存在
28
+ 該網址沒有對應範本 HTTP 406,而且對未登入者是空白 body
29
+ ```
30
+
31
+ **commit 成功不能當作頁面正常的證據。**
32
+
33
+ ## 驗證了什麼,怎麼驗的
34
+
35
+ 全部跑在真實安裝上——WordPress 7.1、WooCommerce 11.1、Mosaic Pro 1.0.7、**未授權**:
36
+ 授權管的是主題庫與更新,不是節點工廠,所以 Pro 型別照樣註冊、照樣渲染。
37
+
38
+ | 項目 | 結果 |
39
+ |---|---|
40
+ | **節點型別** | 122 / 122,一份文件一種型別:寫入 → 渲染 → 斷言 → 刪除。70 RENDERED、30 COMMITTED、15 COMMIT_5xx、7 BROKE_PAGE |
41
+ | **樣式屬性** | 98 / 98 寫進真實頁面並對照編譯後的 CSS:58 COMPILED、18 ABSENT、21 SKIPPED |
42
+ | **節點屬性** | 181 / 181,用每個屬性自己的 validator chain 推導出的值重測:35 APPLIED、42 NO_EFFECT、55 NO_HOST、47 SKIPPED |
43
+ | **響應式** | 兩個站共 569 條 `_t`/`_m` 宣告,對照網站實際送出的樣式表逐條斷言——全數通過 |
44
+ | **主題匯出/匯入** | 完整來回驗證:匯出整個主題、以副本身分匯入,副本送出的頁面逐位元組相同 |
45
+ | **線上量測** | 114 條 REST 路由、151 個 element class、59 個條件主體、23 張表 / 206 個欄位 |
46
+
47
+ `SKIPPED`、`NO_HOST`、`INCONCLUSIVE` 永遠不併進通過率。
48
+ **一支把自己的盲點算成成功的掃描工具,正是這個 skill 要反對的東西。**
49
+
50
+ ### 動手之前值得先知道的兩個結果
51
+
52
+ **帶有 `group` 的屬性,單獨設定一律無效。** 兩個方向都精確:78 個無 group 的屬性得到
53
+ 58 COMPILED、0 ABSENT;20 個有 group 的全部 0 COMPILED。所以 `borderLeftWidth`、
54
+ `outlineColor`、`gridColumnStart` 是**同一條規則的三個實例**,不是三個各自的怪毛病。
55
+ 要用就用群組形狀——`border` 收 `{width, style, color}`——或者退回 `customStyles`。
56
+
57
+ **斷點覆寫只能「改變」屬性,永遠不能「移除」。** 窄螢幕的 `customStyles` 如果只是
58
+ 沒寫某條框線,寬螢幕那條框線會活下來,在塌成單欄的版面正中間畫一條線。
59
+ **要把 `border-left:0` 明講出來。**
60
+
61
+ ## 工具
62
+
63
+ ```bash
64
+ wp eval-file tools/bootstrap_probe_theme.php # 免授權的測試主題
65
+ python tools/build_site.py --config c.json --site sites/moksa.json
66
+ python tools/verify_rwd.py --config c.json --site sites/moksa.json --csv rwd.csv
67
+ python tools/copy_styles.py --config c.json --from a --to-prefix b- --only "&._m"
68
+ wp eval-file tools/theme_export.php active > theme.json
69
+ wp eval-file tools/theme_import.php theme.json "名稱" rebind activate
70
+ ```
71
+
72
+ `sites/_moksa.py` 是完整範例:一個真實工作室的首頁——刊頭、規格區塊、服務、九列作品表格、
73
+ 流程、技術堆疊、產品、客戶見證、聯絡——**590 個節點全部透過資料表寫入**,
74
+ 還有一個用具名 view timeline 做的、會跟著捲動的條款索引,完全沒有 JavaScript。
75
+
76
+ ## 從哪裡開始讀
77
+
78
+ 1. `references/data-model.md` —— 頁面到底住在哪裡。
79
+ 2. `references/write-protocol.md` —— checkout / check / commit。
80
+ 3. `references/failure-modes.md` —— Mosaic 怎麼壞的,都是量出來的。**動筆前先讀。**
81
+ 4. `references/responsive.md` —— state / breakpoint / property 這個軸。
82
+ 5. `references/styling.md` —— 一個樣式值怎麼變成 CSS。
83
+ 6. `references/design-system.md` —— element class 與設計 token。
84
+
85
+ ## 授權
86
+
87
+ MIT。Mosaic Pro 本身是有授權的第三方軟體,**不包含**在這個 repo 裡。