Skip to content

Commit a35fbeb

Browse files
committed
コンフィグの .yaml対応
1 parent 1d40024 commit a35fbeb

6 files changed

Lines changed: 186 additions & 48 deletions

File tree

CLAUDE.md

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,3 @@
1-
# CLAUDE.md
2-
3-
## 【MUST GLOBAL】Gemini活用(プロジェクトのCLAUDE.mdより優先)
4-
5-
### 三位一体の開発原則
6-
ユーザーの**意思決定**、Claudeの**分析と実行**、Geminiの**検証と助言**を組み合わせ、開発の質と速度を最大化する:
7-
- **ユーザー**:プロジェクトの目的・要件・最終ゴールを定義し、最終的な意思決定を行う**意思決定者**
8-
- 反面、具体的なコーディングや詳細な計画を立てる力、タスク管理能力ははありません。
9-
- **Claude**:高度な計画力・高品質な実装・リファクタリング・ファイル操作・タスク管理を担う**実行者**
10-
- 指示に対して忠実に、順序立てて実行する能力はありますが、意志がなく、思い込みは勘違いも多く、思考力は少し劣ります。
11-
- **Gemini**:深いコード理解・Web検索 (Google検索) による最新情報へのアクセス・多角的な視点からの助言・技術的検証を行う**助言者**
12-
- プロジェクトのコードと、インターネット上の膨大な情報を整理し、的確な助言を与えてくれますが、実行力はありません。
13-
14-
### 実践ガイド
15-
- **ユーザーの要求を受けたら即座に`gemini -p <質問内容>`で壁打ち**を必ず実施
16-
- Geminiの意見を鵜呑みにせず、1意見として判断。聞き方を変えて多角的な意見を抽出
17-
- Claude Code内蔵のWebSearchツールは使用しない
18-
- Geminiがエラーの場合は、聞き方を工夫してリトライ:
19-
- ファイル名や実行コマンドを渡す(Geminiがコマンドを実行可能)
20-
- 複数回に分割して聞く
21-
22-
### 主要な活用場面
23-
1. **実現不可能な依頼**: Claude Codeでは実現できない要求への対処 (例: `今日の天気は?`)
24-
2. **前提確認**: ユーザー、Claude自身に思い込みや勘違い、過信がないかどうか逐一確認 (例: `この前提は正しいか?`
25-
3. **技術調査**: 最新情報・エラー解決・ドキュメント検索・調査方法の確認(例: `Rails 7.2の新機能を調べて`
26-
4. **設計検証**: アーキテクチャ・実装方針の妥当性確認(例: `この設計パターンは適切か?`
27-
5. **コードレビュー**: 品質・保守性・パフォーマンスの評価(例: `このコードの改善点は?`
28-
6. **計画立案**: タスクの実行計画レビュー・改善提案(例: `この実装計画の問題点は?`
29-
7. **技術選定**: ライブラリ・手法の比較検討 (例: `このライブラリは他と比べてどうか?`
30-
31-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
32-
331
## Project Overview
342

353
CommandForgeEditor is a visual scripting tool designed for game developers to create and manage scenario scripts (called "skits") without writing code. It provides an intuitive drag-and-drop interface for assembling sequences of commands that control game flow, dialogue, character actions, and other game events.

frontend/src/utils/configLoader.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ const configSchema = {
1818

1919
const validateConfig = ajv.compile(configSchema);
2020

21+
const CONFIG_FILE_NAMES = ['commandForgeEditor.config.yml', 'commandForgeEditor.config.yaml'];
22+
2123
/**
22-
* Loads and validates the commandForgeEditor.config.yml file
24+
* Loads and validates the commandForgeEditor.config.yml or .yaml file
2325
* @param projectPath The project path
2426
* @returns Promise with the configuration
2527
*/
@@ -30,10 +32,17 @@ export async function loadConfigFile(projectPath: string): Promise<CommandForgeC
3032
throw new Error('Running in web environment, Tauri API not available');
3133
}
3234

33-
const configPath = await join(projectPath, 'commandForgeEditor.config.yml');
34-
35-
if (!(await exists(configPath))) {
36-
throw new Error(`Configuration file not found at ${configPath}`);
35+
let configPath: string | null = null;
36+
for (const fileName of CONFIG_FILE_NAMES) {
37+
const path = await join(projectPath, fileName);
38+
if (await exists(path)) {
39+
configPath = path;
40+
break;
41+
}
42+
}
43+
44+
if (!configPath) {
45+
throw new Error(`Configuration file not found. Searched for: ${CONFIG_FILE_NAMES.join(', ')}`);
3746
}
3847

3948
const configContent = await readTextFile(configPath);

frontend/src/utils/devFileSystem.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,39 @@ export async function loadSampleSkit(): Promise<Record<string, Skit>> {
4646
}
4747
}
4848

49+
const CONFIG_FILE_NAMES = ['commandForgeEditor.config.yml', 'commandForgeEditor.config.yaml'];
50+
4951
/**
50-
* 開発環境用: サンプルcommandForgeEditor.config.ymlファイルを読み込む
52+
* 開発環境用: サンプルcommandForgeEditor.config.yml または .yaml ファイルを読み込む
5153
* @returns Promise with the configuration
5254
*/
5355
export async function loadSampleConfig(): Promise<CommandForgeConfig> {
5456
try {
55-
console.log('Loading commandForgeEditor.config.yml for web environment');
56-
57-
// Web環境でfetchを使用してファイルをロード
58-
const response = await fetch('/src/sample/commandForgeEditor.config.yml');
59-
if (!response.ok) {
60-
throw new Error(`Failed to fetch commandForgeEditor.config.yml: ${response.status}`);
57+
console.log('Loading commandForgeEditor.config for web environment');
58+
59+
// Web環境でfetchを使用してファイルをロード (.yml, .yaml の順で試行)
60+
let response: Response | null = null;
61+
let loadedFileName: string | null = null;
62+
63+
for (const fileName of CONFIG_FILE_NAMES) {
64+
const res = await fetch(`/src/sample/${fileName}`);
65+
if (res.ok) {
66+
response = res;
67+
loadedFileName = fileName;
68+
break;
69+
}
70+
}
71+
72+
if (!response || !response.ok) {
73+
throw new Error(`Failed to fetch config file. Searched for: ${CONFIG_FILE_NAMES.join(', ')}`);
6174
}
75+
6276
const content = await response.text();
6377
const config = parse(content) as CommandForgeConfig;
64-
console.log('Successfully loaded commandForgeEditor.config.yml');
78+
console.log(`Successfully loaded ${loadedFileName}`);
6579
return config;
6680
} catch (error) {
67-
console.error('Failed to load commandForgeEditor.config.yml:', error);
81+
console.error('Failed to load commandForgeEditor.config:', error);
6882
throw error;
6983
}
7084
}

memory-bank/activeContext.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- コピーとカット処理の共通化を実施
1616
- 変数機能の仕様書を作成
1717
- ベクター型プロパティの追加とUI更新
18+
- i18n 仕様書を作成
1819

1920
## 現在の課題
2021
- コマンドエディターの詳細機能の把握
@@ -52,4 +53,4 @@
5253
- コマンド編集のユーザーエクスペリエンス改善
5354
- バリデーション機能の拡張
5455
- スキット管理の効率化
55-
- コマンドテンプレート機能の検討
56+
- コマンドテンプレート機能の検討

memory-bank/doc/11-i18n-spec.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# i18n 仕様書(Moore's Command Editor)
2+
3+
本仕様はエディタ UI とプロジェクト(コマンド定義)で利用する翻訳データの構造、配置パス、読み込み規約を定義します。既存実装(frontend/src/i18n 配下)に準拠しています。
4+
5+
## 目的と適用範囲
6+
- エディタ UI 固定文言(アプリ内に同梱。必要に応じて上書き可能)
7+
- プロジェクト側のコマンド/プロパティ名・説明・プレースホルダー・列挙値
8+
- 実行時の読み込み元と優先順位、ファイル命名規則
9+
10+
## 実行時の挙動(概要)
11+
- 初期化: `frontend/src/i18n/config.ts` で i18next を初期化。
12+
- 既定言語: 日本語(`lng: 'ja'`)/フォールバック: 英語(`fallbackLng: 'en'`
13+
- React: Suspense 無効(`useSuspense: false`
14+
- 動的ロード: `frontend/src/i18n/translationLoader.ts``loadTranslations()` がプロジェクト翻訳を追加ロード。
15+
- Tauri 以外(開発/テスト): `frontend/src/sample/i18n/*.json` をフェッチ
16+
- Tauri 実行時: `projectPath/i18n/*.json` をファイル I/O で読み込み
17+
- マージ優先度: アプリ内固定リソース → プロジェクト翻訳で上書き(同一キー)
18+
19+
## 置き場所(JSON パス)
20+
- 開発・テスト用サンプル
21+
- `frontend/src/sample/i18n/english.json`
22+
- `frontend/src/sample/i18n/japanese.json`
23+
- プロダクション(Tauri 実行時のプロジェクト)
24+
- `<projectPath>/i18n/english.json`
25+
- `<projectPath>/i18n/japanese.json`
26+
- `<projectPath>/i18n/chinese.json`
27+
- `<projectPath>/i18n/spanish.json`
28+
29+
備考:
30+
- 実際に言語コードとして使用されるのは各 JSON の `locale` フィールドです(ファイル名は検出対象の候補)。
31+
- `projectPath` はアプリのストアで選択されたプロジェクトルートです(`useSkitStore.getState().projectPath`)。
32+
33+
## JSON フォーマット(厳密定義)
34+
TypeScript による型定義(参考):
35+
36+
```ts
37+
// 言語コードは BCP 47 推奨(例: 'en', 'ja', 'zh', 'es' など)
38+
export type LocaleCode = string;
39+
40+
export interface TranslationFile {
41+
locale: LocaleCode; // 必須: 使用する言語コード
42+
name: string; // 必須: 言語表示名(例: "English", "日本語")
43+
translations: Record<string, string>; // 必須: 翻訳キー → 文字列
44+
}
45+
```
46+
47+
必須キー:
48+
- `locale`: 例 `"en"`, `"ja"`
49+
- `name`: 例 `"English"`, `"Japanese"`
50+
- `translations`: 平坦(フラット)なキーの辞書。値はすべて文字列。
51+
52+
## 翻訳キー設計(命名規則)
53+
- UI 固定文言(アプリ同梱; プロジェクトで上書き可)
54+
- `editor.*`(メニュー、ツールバー、パネル、ダイアログ、バリデーション、共通ラベル)
55+
- `language.*`(言語 UI 用のラベル群)
56+
- `skitList.*`
57+
- コマンド関連(プロジェクト側が提供)
58+
- 基本:
59+
- `command.{commandId}.name`
60+
- `command.{commandId}.description`
61+
- プロパティ:
62+
- `command.{commandId}.property.{propKey}.name`
63+
- `command.{commandId}.property.{propKey}.description`
64+
- `command.{commandId}.property.{propKey}.placeholder`
65+
- 列挙値(enum がある場合):
66+
- `command.{commandId}.property.{propKey}.enum.{EnumValue}`
67+
68+
生成ヘルパー: `generateCommandTranslationKeys(command)` が上記パターンのキー一覧を生成。
69+
70+
注意:
71+
- キーはドット区切りのフラット文字列。入れ子 JSON は使用しません。
72+
- `{EnumValue}` は元定義の値と完全一致(大文字小文字・スペース含む)。
73+
74+
## 文字列の書式と補間
75+
- 補間(i18next 互換 Mustache 形式): `{{name}}`, `{{count}}` など
76+
- 例: `editor.toolbar.commandAdded: "{{command}} added"`
77+
- HTML は原則含めない(エスケープに依存しない安全な表現を推奨)
78+
- 改行が必要な場合は `\n` を利用
79+
80+
## 言語の検出・選択
81+
- 既定: 日本語(`ja`
82+
- フォールバック: 英語(`en`
83+
- 開発モードでは `localStorage.i18nextLng``ja` に設定(`src/main.tsx`
84+
- 利用可能言語の一覧はロード済みリソースから算出(`getAvailableLanguages()`
85+
86+
## マージと優先度
87+
1. アプリ内固定翻訳(`config.ts``editorTranslations`)が初期ロード
88+
2. プロジェクト翻訳(`translationLoader.ts`)を同一 `namespace: 'translation'` に追加入力
89+
3. 同一キーが存在する場合、プロジェクト側で上書き
90+
91+
## バリデーション・品質チェック
92+
- JSON が妥当(コメント不可・UTF-8 推奨)
93+
- `locale` が正しい(BCP 47 準拠を推奨、例: `en`, `ja`
94+
- `translations` の値はすべて非空文字列
95+
- 重複キーなし(同一ファイル内)
96+
- 列挙値キーの末尾 `{EnumValue}` は元データ定義と完全一致
97+
- 必要キー(`name`, `description` 等)が網羅されていること(`generateCommandTranslationKeys` で検出可)
98+
99+
## 拡張と追加言語
100+
- 新しい言語を追加するには `<projectPath>/i18n/{languageName}.json` を作成し、`locale` に適切なコードを設定
101+
- ローダーはファイル名 `english|japanese|chinese|spanish` を探索しますが、実際の適用言語は JSON 内の `locale` に従います
102+
- 追加の言語ファイル拡張を行う場合は、ローダー側の探索リスト拡張が必要です
103+
104+
## 例(最小)
105+
`english.json`
106+
```json
107+
{
108+
"locale": "en",
109+
"name": "English",
110+
"translations": {
111+
"command.text.name": "Text",
112+
"command.text.description": "Display dialogue",
113+
"command.text.property.body.name": "Body",
114+
"command.text.property.body.description": "Dialogue content",
115+
"command.text.property.body.placeholder": "Enter dialogue text"
116+
}
117+
}
118+
```
119+
120+
`japanese.json`
121+
```json
122+
{
123+
"locale": "ja",
124+
"name": "日本語",
125+
"translations": {
126+
"command.text.name": "テキスト",
127+
"command.text.description": "セリフを表示",
128+
"command.text.property.body.name": "本文",
129+
"command.text.property.body.description": "セリフ内容",
130+
"command.text.property.body.placeholder": "セリフを入力"
131+
}
132+
}
133+
```
134+
135+
## 関連ソース
136+
- 設定: `frontend/src/i18n/config.ts`
137+
- ローダー: `frontend/src/i18n/translationLoader.ts`
138+
- 初期化: `frontend/src/main.tsx`
139+
- サンプル: `frontend/src/sample/i18n/*.json`
140+
141+
## 運用メモ
142+
- プロジェクト翻訳で UI 固定キー(`editor.*` 等)を定義すると同梱文言を上書き可能。ただし、推奨はコマンド関連キーの提供。
143+
- JSON 変更の反映にはアプリの再読み込みが必要。
144+
- 型の観点から、`translations``Record<string, string>` を維持し、曖昧な `any` の使用は避けること。
145+

memory-bank/progress.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- ✅ コピーとカット処理の共通化を実施
1111
- ✅ 変数機能の仕様書を作成
1212
- ✅ ベクター型プロパティの実装とUIへの入力フィールド追加
13+
- ✅ i18n 仕様書を作成
1314

1415
## 現在の状態
1516
プロジェクトはまだ分析段階にあります。Moore's Command Editorのコードベースと機能を理解し、ドキュメント化している段階です。メモリバンクの基本構造が確立され、今後の開発のための基盤が整いました。
@@ -50,4 +51,4 @@
5051
1. コードベースの詳細理解
5152
2. 主要機能の動作確認
5253
3. 改善点の特定
53-
4. 開発ロードマップの作成
54+
4. 開発ロードマップの作成

0 commit comments

Comments
 (0)