ルール策定前に書かれた設計ドキュメント7点を、以降の基準点として そのままの状態で記録する。CLAUDE.md のルール1〜4は未適用。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MdLT5x5ka5y6CaWLeE3EKb
6.5 KiB
6.5 KiB
KLE JSON 互換性設計
双方向変換戦略
Beyond KLE → KLE JSON
1. フラット化プロセス
interface ConversionOptions {
preserveIds: boolean; // IDを保持するか
preserveClusterInfo: boolean; // クラスター情報を保持するか
idEmbedMethod: 'metadata' | 'label' | 'comment';
}
function convertToKLE(beyondKle: PHYLayer, options: ConversionOptions): KLELayout {
const flatKeys = flattenElements(beyondKle.elements);
return {
name: beyondKle.metadata.name,
keys: flatKeys.map(key => convertKey(key, options))
};
}
function flattenElements(elements: Element[], parentTransform?: Transform): FlatKey[] {
const result: FlatKey[] = [];
for (const element of elements) {
if (element.type === 'key') {
const absolutePos = applyTransform(element.position, parentTransform);
result.push({
...element,
absolutePosition: absolutePos,
clusterPath: getClusterPath(element)
});
} else if (element.type === 'cluster') {
const clusterTransform = combineTransforms(parentTransform, element.position);
result.push(...flattenElements(element.elements, clusterTransform));
}
}
return result;
}
2. ID保持方法の比較
| 方法 | メリット | デメリット | KLE互換性 |
|---|---|---|---|
_beyondkle メタデータ |
構造化された情報保持 | KLEパーサーが無視する可能性 | △ |
| ラベル9番目位置 | 確実に保存される | 表示されてしまう | ○ |
| コメントフィールド | 非表示 | 標準的でない | △ |
3. 推奨アプローチ: ハイブリッド方式
{
"name": "Split Layout (Generated by Beyond KLE)",
"_beyondkle": {
"version": "1.0.0",
"sourceFile": "layout.beyond.json",
"conversionSettings": {
"flattenClusters": true,
"preserveRotations": true
}
},
"keys": [
{
"x": 0, "y": 0, "w": 1, "h": 1,
"t": "#000000\n\n\n\n\n\n\n\n\nk00",
"_beyondkle": {
"id": "k00",
"clusterPath": ["left_half", "left_main"],
"relativePosition": { "x": 0, "y": 0 },
"absolutePosition": { "x": 0, "y": 0 }
}
}
]
}
KLE JSON → Beyond KLE
1. ID復元戦略
function convertFromKLE(kleLayout: KLELayout): PHYLayer {
// 1. メタデータからBeyond KLE情報を取得
const beyondKleInfo = kleLayout._beyondkle;
if (beyondKleInfo?.sourceFile) {
// 元のBeyond KLEファイルが指定されている場合
return reconstructFromSource(kleLayout, beyondKleInfo);
}
// 2. キーからIDとクラスター情報を抽出
const keys = kleLayout.keys.map(kleKey => {
const id = extractId(kleKey);
const clusterInfo = extractClusterInfo(kleKey);
return {
type: 'key' as const,
id: id || generateId(kleKey),
profile: 'default',
position: { x: kleKey.x, y: kleKey.y },
size: { width: kleKey.w || 1, height: kleKey.h || 1 },
metadata: extractMetadata(kleKey)
};
});
// 3. クラスター構造の再構築
return reconstructClusters(keys);
}
function extractId(kleKey: any): string | null {
// 1. _beyondkle メタデータから
if (kleKey._beyondkle?.id) return kleKey._beyondkle.id;
// 2. ラベル9番目から
if (kleKey.labels?.[8]) return kleKey.labels[8];
// 3. t文字列の解析
const tMatch = kleKey.t?.match(/\n([a-zA-Z0-9_]+)$/);
if (tMatch) return tMatch[1];
return null;
}
2. クラスター再構築アルゴリズム
function reconstructClusters(flatKeys: Key[]): Element[] {
// クラスター情報が保持されている場合
const clusteredKeys = groupByCluster(flatKeys);
if (Object.keys(clusteredKeys).length > 1) {
return Object.entries(clusteredKeys).map(([clusterName, keys]) => ({
type: 'cluster' as const,
id: clusterName,
name: clusterName,
position: calculateClusterOrigin(keys),
elements: keys.map(key => ({
...key,
position: makeRelativeToCluster(key.position, clusterOrigin)
}))
}));
}
// クラスター情報がない場合は自動推定
return autoDetectClusters(flatKeys);
}
function autoDetectClusters(keys: Key[]): Element[] {
// 座標の近さとレイアウトパターンからクラスターを推定
// 1. 連続する矩形領域の検出
// 2. 回転角度の類似性
// 3. 一定の間隔での分離
const clusters = detectSpatialClusters(keys);
if (clusters.length === 1) {
// 単一クラスターの場合はフラットに
return keys;
}
return clusters;
}
実装における考慮事項
1. バージョン管理
{
"_beyondkle": {
"version": "1.0.0",
"generator": "beyond-kle-converter",
"timestamp": "2025-11-09T12:00:00Z",
"preservedData": {
"clusters": true,
"rotations": true,
"profiles": false
}
}
}
2. 設定可能な変換オプション
interface ConversionSettings {
// ID保持方法
idPreservation: 'metadata' | 'label' | 'both' | 'none';
// クラスター処理
clusterHandling: 'preserve' | 'flatten' | 'auto';
// 回転の処理
rotationHandling: 'preserve' | 'flatten';
// プロファイル情報
includeProfiles: boolean;
// 互換性レベル
compatibilityLevel: 'strict' | 'extended' | 'beyondkle';
}
3. 往復変換の整合性保証
// テストケース
const originalBeyondKLE = loadBeyondKLE('test.beyond.json');
const kleJson = convertToKLE(originalBeyondKLE, settings);
const reconstructed = convertFromKLE(kleJson);
// 構造的等価性の検証
assert(structurallyEquivalent(originalBeyondKLE, reconstructed));
ワークフロー例
1. Beyond KLE → 外部ツール → Beyond KLE
# Beyond KLE → KLE JSON (ID付き)
beyond-kle export --format=kle --preserve-ids layout.beyond.json
# 外部ツール(KLE等)で編集
# ...
# KLE JSON → Beyond KLE (構造復元)
beyond-kle import --format=kle --auto-cluster edited.kle.json
2. 段階的移行
# 既存のKLE JSON → Beyond KLE
beyond-kle import legacy.kle.json
# Beyond KLE で編集・管理
# 必要に応じてKLE JSONで共有
beyond-kle export --format=kle-compatible project.beyond.json
この設計により、Beyond KLEの高度な機能を使いながらも、既存のKLEエコシステムとの互換性を保てると思いますが、いかがでしょうか?