# Phase 1: JSON Schema仕様策定 ## レイヤー間データフロー ``` PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キーマップ) ↓ ↓ ファームウェア生成 VIA/Remap出力 ``` ## 1. PHYレイヤー JSON Schema 座標・回転・サイズの意味は `PHYレイヤー.md` を正とする。 ### 基本構造 ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://beyond-kle.org/schemas/phy-layer.json", "title": "PHY Layer - Physical Key Layout", "description": "Physical positioning and sizing of keys", "type": "object", "required": ["version", "metadata", "profiles", "root"], "properties": { "version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$", "description": "Schema version (semver)" }, "metadata": { "type": "object", "properties": { "name": { "type": "string" }, "author": { "type": "string" }, "description": { "type": "string" }, "created": { "type": "string", "format": "date-time" }, "modified": { "type": "string", "format": "date-time" } } }, "compatibility": { "type": "object", "description": "Information for external tool compatibility", "properties": { "kleJson": { "type": "object", "properties": { "source": { "type": "string" }, "checksum": { "type": "string" }, "preservedFields": { "type": "array", "items": { "type": "string" } } } }, "originalFormat": { "type": "string", "enum": ["kle", "via", "qmk", "native"] } } }, "profiles": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/profile" } }, "root": { "type": "array", "items": { "oneOf": [ { "$ref": "#/$defs/key" }, { "$ref": "#/$defs/cluster" } ] } } }, "$defs": { "transform": { "type": "object", "description": "Placement relative to the parent: rotate by rotation around the local origin, then translate by (x, y)", "required": ["x", "y", "rotation"], "properties": { "x": { "type": "number" }, "y": { "type": "number" }, "rotation": { "type": "number", "description": "Degrees" } } }, "profile": { "type": "object", "required": ["id", "name", "unitSize"], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "unitSize": { "type": "object", "required": ["x", "y"], "properties": { "x": { "type": "number", "minimum": 0 }, "y": { "type": "number", "minimum": 0 } } }, "visualOffset": { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" }, "radius": { "type": "number", "minimum": 0 } } } } }, "key": { "type": "object", "required": ["type", "id", "profile", "transform", "size"], "properties": { "type": { "type": "string", "const": "key" }, "id": { "type": "string", "description": "Unique key identifier" }, "profile": { "type": "string", "description": "Reference to profile ID" }, "transform": { "$ref": "#/$defs/transform" }, "size": { "type": "object", "description": "Local size. Not affected by the parent transform", "required": ["w", "h"], "properties": { "w": { "type": "number", "minimum": 0 }, "h": { "type": "number", "minimum": 0 } } }, "metadata": { "type": "object", "properties": { "label": { "type": "string" }, "color": { "type": "string" }, "textColor": { "type": "string" }, "kleCompatibility": { "type": "object", "description": "Original KLE fields for round-trip compatibility", "properties": { "labels": { "type": "array", "items": { "type": "string" } }, "textSizes": { "type": "array", "items": { "type": "number" } }, "decalData": { "type": "object" } } } } } } }, "cluster": { "type": "object", "required": ["type", "id", "name", "transform", "children"], "properties": { "type": { "type": "string", "const": "cluster" }, "id": { "type": "string" }, "name": { "type": "string" }, "transform": { "$ref": "#/$defs/transform" }, "children": { "type": "array", "items": { "oneOf": [ { "$ref": "#/$defs/key" }, { "$ref": "#/$defs/cluster" } ] } } } } } } ``` ### 使用例 ```json { "version": "1.0.0", "metadata": { "name": "Split Keyboard Layout", "author": "John Doe", "description": "Ergonomic split keyboard with rotated thumb clusters", "created": "2025-01-01T00:00:00Z" }, "profiles": [ { "id": "standard", "name": "Standard Cherry MX", "unitSize": { "x": 19.05, "y": 19.05 }, "visualOffset": { "x": 1, "y": 1, "radius": 1 } } ], "root": [ { "type": "cluster", "id": "left_main", "name": "Left Main Block", "transform": { "x": 0, "y": 0, "rotation": 0 }, "children": [ { "type": "key", "id": "k00", "profile": "standard", "transform": { "x": 0, "y": 0, "rotation": 0 }, "size": { "w": 1, "h": 1 }, "metadata": { "label": "Q" } }, { "type": "key", "id": "k01", "profile": "standard", "transform": { "x": 1, "y": 0, "rotation": 0 }, "size": { "w": 1, "h": 1 }, "metadata": { "label": "W" } } ] }, { "type": "cluster", "id": "left_thumb", "name": "Left Thumb Cluster", "transform": { "x": 2, "y": 3, "rotation": 15 }, "children": [ { "type": "key", "id": "k30", "profile": "standard", "transform": { "x": 0, "y": 0, "rotation": 0 }, "size": { "w": 1.25, "h": 1 }, "metadata": { "label": "Space" } }, { "type": "key", "id": "k31", "profile": "standard", "transform": { "x": 1.25, "y": 0, "rotation": 0 }, "size": { "w": 1, "h": 1 }, "metadata": { "label": "Enter" } } ] } ] } ``` ## 2. IDXレイヤー JSON Schema ### 基本構造 ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://beyond-kle.org/schemas/idx-layer.json", "title": "IDX Layer - Key Identification", "description": "Mapping between physical keys and logical identifiers", "type": "object", "required": ["version", "phyReference", "keyMap"], "properties": { "version": { "type": "string" }, "phyReference": { "type": "object", "required": ["source", "checksum"], "properties": { "source": { "type": "string" }, "checksum": { "type": "string" } } }, "keyMap": { "type": "array", "items": { "$ref": "#/$defs/keyMapping" } } }, "$defs": { "keyMapping": { "type": "object", "required": ["physicalId", "logicalId"], "properties": { "physicalId": { "type": "string", "description": "Reference to PHY layer key ID" }, "logicalId": { "type": "object", "required": ["index"], "properties": { "index": { "type": "integer", "minimum": 0 }, "matrix": { "type": "object", "properties": { "row": { "type": "integer", "minimum": 0 }, "col": { "type": "integer", "minimum": 0 } } }, "label": { "type": "string" } } } } } } } ``` ## 3. ELCレイヤー JSON Schema ### 基本構造 ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://beyond-kle.org/schemas/elc-layer.json", "title": "ELC Layer - Electrical Configuration", "description": "Electrical wiring and pin mapping", "type": "object", "required": ["version", "idxReference", "microcontroller", "matrix"], "properties": { "version": { "type": "string" }, "idxReference": { "type": "object", "required": ["source", "checksum"], "properties": { "source": { "type": "string" }, "checksum": { "type": "string" } } }, "microcontroller": { "type": "object", "required": ["type", "pinMapping"], "properties": { "type": { "type": "string" }, "pinMapping": { "type": "object", "properties": { "rows": { "type": "array", "items": { "type": "string" } }, "cols": { "type": "array", "items": { "type": "string" } } } } } }, "matrix": { "type": "object", "required": ["type", "dimensions"], "properties": { "type": { "type": "string", "enum": ["standard", "charlieplexing", "direct"] }, "dimensions": { "type": "object", "required": ["rows", "cols"], "properties": { "rows": { "type": "integer", "minimum": 1 }, "cols": { "type": "integer", "minimum": 1 } } } } } } } ``` ## 4. MAPレイヤー JSON Schema ### 基本構造 ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://beyond-kle.org/schemas/map-layer.json", "title": "MAP Layer - Keymap Configuration", "description": "Key code assignments and layers", "type": "object", "required": ["version", "idxReference", "layers"], "properties": { "version": { "type": "string" }, "idxReference": { "type": "object", "required": ["source", "checksum"], "properties": { "source": { "type": "string" }, "checksum": { "type": "string" } } }, "layers": { "type": "array", "items": { "$ref": "#/$defs/layer" } } }, "$defs": { "layer": { "type": "object", "required": ["id", "name", "keymap"], "properties": { "id": { "type": "integer", "minimum": 0 }, "name": { "type": "string" }, "keymap": { "type": "array", "items": { "$ref": "#/$defs/keyAssignment" } } } }, "keyAssignment": { "type": "object", "required": ["keyIndex", "keycode"], "properties": { "keyIndex": { "type": "integer" }, "keycode": { "type": "string" } } } } } ``` ## 変換フロー設計 ### PHY → IDX変換 1. PHYレイヤーから物理キーリストを取得 2. 各キーに論理IDを割り当て 3. マトリックス座標の自動生成(行列最適化) ### IDX → ELC変換 1. マトリックス次元を算出 2. ピン配置の最適化提案 3. 配線効率の検証 ### IDX + ELC → MAP変換 1. キーインデックス配列の生成 2. デフォルトキーマップの提案 3. VIA/QMK形式への出力 ## 次のステップ 1. **TypeScriptでの型定義作成** 2. **変換ロジックのプロトタイプ実装** 3. **テストケース(60%、Split等)での検証** 4. **既存KLE JSONからの変換機能**