template-ts-implementation.json•11.9 kB
{
  "schema": "memory_document_v2",
  "metadata": {
    "id": "template-ts-implementation",
    "title": "テンプレートTS化の実装手順詳細",
    "documentType": "implementation_plan",
    "path": "template-ts-implementation.json",
    "tags": [],
    "createdAt": "2025-04-11T12:45:00.000Z",
    "lastModified": "2025-04-11T11:50:13.656Z"
  },
  "content": {
    "sections": [
      {
        "title": "実装ステップ概要",
        "content": "テンプレートをJSONからTypeScriptに移行する実装は以下のステップで行います:\n\n1. definitions ディレクトリの作成とセットアップ\n2. 最初のテンプレート(rules)のTS化\n3. JsonTemplateLoader の拡張\n4. テスト環境の整備\n5. 残りのテンプレートの順次移行"
      },
      {
        "title": "Step 1: テンプレート定義ディレクトリのセットアップ",
        "content": "### 1.1 ディレクトリ作成\n```bash\nmkdir -p /Users/tmita/workspace/memory-bank-mcp-server/packages/mcp/src/templates/definitions\n```\n\n### 1.2 index.tsファイルの作成\n```typescript\n// /packages/mcp/src/templates/definitions/index.ts\n\n// 各テンプレート定義をここでエクスポート\nexport * from './rules';\n// 他のテンプレートも順次追加していく\n```\n\nこのファイルは、すべてのテンプレート定義をエクスポートする役割を担います。新しいテンプレートを追加するたびに、このファイルにエクスポート文を追加します。"
      },
      {
        "title": "Step 2: rulesテンプレートのTS化",
        "content": "### 2.1 rulesテンプレートの実装\n\n```typescript\n// /packages/mcp/src/templates/definitions/rules.ts\nimport { Template } from '../types';\n\nexport const rulesTemplate: Template = {\n  schema: \"template_v1\",\n  metadata: {\n    id: \"rules\",\n    titleKey: \"template.title.rules\",\n    descriptionKey: \"template.description.rules\",\n    type: \"system\",\n    lastModified: \"2025-04-11T12:45:00.000Z\"\n  },\n  content: {\n    sections: [\n      {\n        id: \"branchMemoryGuidelines\",\n        titleKey: \"template.section.branchMemoryGuidelines\",\n        contentKey: \"template.content.branchMemoryGuidelines\",\n        isOptional: false\n      },\n      {\n        id: \"branchContextJson\",\n        titleKey: \"template.section.branchContextJson\",\n        contentKey: \"template.content.branchContextJson\",\n        isOptional: false\n      },\n      {\n        id: \"activeContextJson\",\n        titleKey: \"template.section.activeContextJson\",\n        contentKey: \"template.content.activeContextJson\",\n        isOptional: false\n      },\n      {\n        id: \"progressJson\",\n        titleKey: \"template.section.progressJson\",\n        contentKey: \"template.content.progressJson\",\n        isOptional: false\n      },\n      {\n        id: \"systemPatternsJson\",\n        titleKey: \"template.section.systemPatternsJson\",\n        contentKey: \"template.content.systemPatternsJson\",\n        isOptional: false\n      },\n      {\n        id: \"bestPractices\",\n        titleKey: \"template.section.bestPractices\",\n        contentKey: \"template.content.bestPractices\",\n        isOptional: false\n      }\n    ],\n    placeholders: {}\n  }\n};\n```"
      },
      {
        "title": "Step 3: JsonTemplateLoaderの拡張",
        "content": "### 3.1 JsonTemplateLoader.tsの修正\n\n```typescript\n// /packages/mcp/src/infrastructure/templates/JsonTemplateLoader.ts の修正\n\n/**\n * JSON Template Loader\n * Loads and processes JSON templates with internationalization support\n */\nimport path from 'node:path';\nimport * as fs from 'fs';\n// 型定義を更新\nimport { Template } from '../../templates/types.js';\n// テンプレート定義をインポート\nimport * as templateDefinitions from '../../templates/definitions/index.js';\n\n// 型エイリアスの更新\ntype JsonTemplate = Template;\nconst validateJsonTemplate = (data: Record<string, unknown>): Template => data as Template; // 暫定対応を継続\ntype Language = 'en' | 'ja' | 'zh';\nimport { IFileSystemService } from '../storage/interfaces/IFileSystemService.js';\nimport { II18nProvider } from '../i18n/interfaces/II18nProvider.js';\nimport { TemplateRenderer } from './TeplateRenderer.js';\nimport { ITemplateLoader } from './interfaces/ITemplateLoader.js';\nimport { logger } from '../../shared/utils/logger.js';\n\n/**\n * Implementation of ITemplateLoader for JSON templates\n */\nexport class JsonTemplateLoader implements ITemplateLoader {\n  private readonly templateRenderer: TemplateRenderer;\n\n  // Legacy patterns removed as per user request\n\n  /**\n   * Constructor\n   *\n   * @param fileSystemService Service for file system operations\n   * @param i18nProvider Provider for internationalization services\n   */\n  constructor(\n    private readonly fileSystemService: IFileSystemService,\n    private readonly i18nProvider: II18nProvider\n  ) {\n    this.templateRenderer = new TemplateRenderer(i18nProvider);\n  }\n\n  /**\n   * Gets the JSON templates directory path\n   */\n  private getJsonTemplatesDirectory(): string {\n    // パス解決部分はそのまま残します(後方互換性のため)\n    // ...\n  }\n\n  /**\n   * テンプレートIDをTypeScript変数名に変換\n   * 例: 'rules-ja' → 'rulesJaTemplate'\n   * 例: 'active-context' → 'activeContextTemplate'\n   */\n  private getTypeScriptTemplateName(templateId: string): string {\n    return `${templateId.replace(/[-]+/g, '').replace(/([a-z])[-]([a-z])/g, (_, p1, p2) => p1 + p2.toUpperCase())}Template`;\n  }\n\n  /**\n   * Implements ITemplateLoader.loadJsonTemplate\n   */\n  async loadJsonTemplate(templateId: string): Promise<JsonTemplate> {\n    // 1. メモリ内の定義をチェック\n    const tsTemplateName = this.getTypeScriptTemplateName(templateId);\n    \n    // @ts-ignore - インデックスシグネチャが型システム上は定義されていないため\n    if (templateDefinitions[tsTemplateName]) {\n      // @ts-ignore\n      logger.debug(`Found in-memory template '${templateId}' as '${tsTemplateName}'`);\n      // @ts-ignore\n      return templateDefinitions[tsTemplateName];\n    }\n    \n    // 2. 次にファイルシステムをチェック (後方互換性のため)\n    const templatePath = path.join(this.getJsonTemplatesDirectory(), `${templateId}.json`);\n    \n    logger.debug(`Trying to load template '${templateId}' from path: ${templatePath}`);\n\n    try {\n      // ファイル存在チェックと読み込み処理は既存のまま...\n      // ...\n    } catch (error) {\n      // エラー処理は既存のまま...\n      // ...\n    }\n  }\n\n  // その他のメソッドはそのまま...\n}\n```\n\n### 3.2 ITemplateLoader.tsの修正\n\n```typescript\n// /packages/mcp/src/infrastructure/templates/interfaces/ITemplateLoader.ts の修正\n\n/**\n * Template Loader Interface\n * Defines the contract for loading and processing templates\n */\nimport { Language } from '../../../domain/i18n/Language.js';\nimport { Template } from '../../../templates/types.js';\n\n// 型エイリアスの更新\ntype JsonTemplate = Template;\n\n/**\n * Interface for template loading and rendering functionality\n */\nexport interface ITemplateLoader {\n  // 既存のインターフェース定義をそのまま使用\n  // ただし型参照は更新する\n  // ...\n}\n```"
      },
      {
        "title": "Step 4: テスト環境の整備",
        "content": "### 4.1 テスト用のモックテンプレートの作成\n\n```typescript\n// /packages/mcp/tests/mocks/templates.ts\n\nimport { Template } from '../../src/templates/types';\n\nexport const mockRulesTemplate: Template = {\n  schema: \"template_v1\",\n  metadata: {\n    id: \"rules\",\n    titleKey: \"template.title.rules\",\n    descriptionKey: \"template.description.rules\",\n    type: \"system\",\n    lastModified: \"2025-04-11T12:45:00.000Z\"\n  },\n  content: {\n    sections: [\n      {\n        id: \"test-section\",\n        titleKey: \"template.section.test\",\n        contentKey: \"template.content.test\",\n        isOptional: false\n      }\n    ],\n    placeholders: {}\n  }\n};\n\n// 他のテスト用テンプレートも必要に応じて追加\n```\n\n### 4.2 JsonTemplateLoaderのテスト修正\n\n既存のテストを確認し、必要に応じて修正します。特にメモリ内テンプレート定義を活用するテストケースを追加することで、パス解決の問題に依存しないテストが可能になります。"
      },
      {
        "title": "Step 5: 残りのテンプレートの移行",
        "content": "### 5.1 優先順位\n\n以下の優先順位で残りのテンプレートを移行します:\n\n1. `active-context-template.json`\n2. `branch-context-template.json`\n3. `system-patterns-template.json`\n4. `progress-template.json`\n5. 残りのテンプレート\n\n### 5.2 移行手順\n\n各テンプレートに対して以下の手順を実施します:\n\n1. JSONファイルの内容を確認\n2. TypeScriptファイルを作成(例:`activeContextTemplate.ts`)\n3. `index.ts`にエクスポート文を追加\n4. テストを作成または更新\n5. 動作確認\n\n### 5.3 既存JSONファイルの扱い\n\n後方互換性のために、しばらくは既存のJSONファイルも残しておきます。完全に移行が完了し、安定動作が確認できた後に、不要なJSONファイルを削除することを検討します。"
      },
      {
        "title": "テスト戦略",
        "content": "### テスト対象\n\n1. **`JsonTemplateLoader`**:\n   - メモリ内テンプレート読み込みのテスト\n   - フォールバックとしてのJSONファイル読み込みのテスト\n   - 存在しないテンプレートへのアクセス時のエラーハンドリングテスト\n\n2. **`テンプレート定義`**:\n   - 各テンプレート定義の構造検証テスト\n   - テンプレートのスキーマバージョン確認テスト\n\n### テスト方法\n\n1. **単体テスト**:\n   - Vitestを使用した通常の単体テスト\n   - モック`IFileSystemService`と`II18nProvider`を使用\n\n2. **インテグレーションテスト**:\n   - 実際のテンプレートを使用したテスト\n   - テンプレート読み込みから翻訳・レンダリングまでの全体フロー検証"
      },
      {
        "title": "実装におけるリスクと対策",
        "content": "| リスク | 対策 |\n|-------|------|\n| テンプレート変数名の正規表現による変換ミス | 十分なテストケースでエッジケースをカバー |\n| 既存の呼び出し箇所と新実装の互換性問題 | 同一インターフェースを維持し、内部実装のみ変更 |\n| CI環境での動作問題 | CI用のテストケースを追加し、特にパス解決を検証 |\n| 既存JSONファイルとの整合性維持の困難さ | 移行期間中は更新の都度、両方を同期する |\n| インポートパスの問題 | ESModules対応に注意し、`.js`拡張子を適切に付与 |"
      },
      {
        "title": "コミット計画",
        "content": "以下のコミット単位で実装を進めます:\n\n1. テンプレート定義ディレクトリとindex.tsの作成\n2. rulesテンプレートのTS実装\n3. JsonTemplateLoaderの拡張実装\n4. テスト環境の整備\n5. コアテンプレート(active-context, branch-context, system-patterns, progress)のTS化\n6. 残りのテンプレートのTS化\n\n各コミットは、単体テストが通過することを確認してからプッシュします。"
      }
    ]
  }
}