@llm-translate/cli 1.0.0-next.1

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 (157) hide show
  1. package/.dockerignore +51 -0
  2. package/.env.example +33 -0
  3. package/.github/workflows/docs-pages.yml +57 -0
  4. package/.github/workflows/release.yml +49 -0
  5. package/.translaterc.json +44 -0
  6. package/CLAUDE.md +243 -0
  7. package/Dockerfile +55 -0
  8. package/README.md +371 -0
  9. package/RFC.md +1595 -0
  10. package/dist/cli/index.d.ts +2 -0
  11. package/dist/cli/index.js +4494 -0
  12. package/dist/cli/index.js.map +1 -0
  13. package/dist/index.d.ts +1152 -0
  14. package/dist/index.js +3841 -0
  15. package/dist/index.js.map +1 -0
  16. package/docker-compose.yml +56 -0
  17. package/docs/.vitepress/config.ts +161 -0
  18. package/docs/api/agent.md +262 -0
  19. package/docs/api/engine.md +274 -0
  20. package/docs/api/index.md +171 -0
  21. package/docs/api/providers.md +304 -0
  22. package/docs/changelog.md +64 -0
  23. package/docs/cli/dir.md +243 -0
  24. package/docs/cli/file.md +213 -0
  25. package/docs/cli/glossary.md +273 -0
  26. package/docs/cli/index.md +129 -0
  27. package/docs/cli/init.md +158 -0
  28. package/docs/cli/serve.md +211 -0
  29. package/docs/glossary.json +235 -0
  30. package/docs/guide/chunking.md +272 -0
  31. package/docs/guide/configuration.md +139 -0
  32. package/docs/guide/cost-optimization.md +237 -0
  33. package/docs/guide/docker.md +371 -0
  34. package/docs/guide/getting-started.md +150 -0
  35. package/docs/guide/glossary.md +241 -0
  36. package/docs/guide/index.md +86 -0
  37. package/docs/guide/ollama.md +515 -0
  38. package/docs/guide/prompt-caching.md +221 -0
  39. package/docs/guide/providers.md +232 -0
  40. package/docs/guide/quality-control.md +206 -0
  41. package/docs/guide/vitepress-integration.md +265 -0
  42. package/docs/index.md +63 -0
  43. package/docs/ja/api/agent.md +262 -0
  44. package/docs/ja/api/engine.md +274 -0
  45. package/docs/ja/api/index.md +171 -0
  46. package/docs/ja/api/providers.md +304 -0
  47. package/docs/ja/changelog.md +64 -0
  48. package/docs/ja/cli/dir.md +243 -0
  49. package/docs/ja/cli/file.md +213 -0
  50. package/docs/ja/cli/glossary.md +273 -0
  51. package/docs/ja/cli/index.md +111 -0
  52. package/docs/ja/cli/init.md +158 -0
  53. package/docs/ja/guide/chunking.md +271 -0
  54. package/docs/ja/guide/configuration.md +139 -0
  55. package/docs/ja/guide/cost-optimization.md +30 -0
  56. package/docs/ja/guide/getting-started.md +150 -0
  57. package/docs/ja/guide/glossary.md +214 -0
  58. package/docs/ja/guide/index.md +32 -0
  59. package/docs/ja/guide/ollama.md +410 -0
  60. package/docs/ja/guide/prompt-caching.md +221 -0
  61. package/docs/ja/guide/providers.md +232 -0
  62. package/docs/ja/guide/quality-control.md +137 -0
  63. package/docs/ja/guide/vitepress-integration.md +265 -0
  64. package/docs/ja/index.md +58 -0
  65. package/docs/ko/api/agent.md +262 -0
  66. package/docs/ko/api/engine.md +274 -0
  67. package/docs/ko/api/index.md +171 -0
  68. package/docs/ko/api/providers.md +304 -0
  69. package/docs/ko/changelog.md +64 -0
  70. package/docs/ko/cli/dir.md +243 -0
  71. package/docs/ko/cli/file.md +213 -0
  72. package/docs/ko/cli/glossary.md +273 -0
  73. package/docs/ko/cli/index.md +111 -0
  74. package/docs/ko/cli/init.md +158 -0
  75. package/docs/ko/guide/chunking.md +271 -0
  76. package/docs/ko/guide/configuration.md +139 -0
  77. package/docs/ko/guide/cost-optimization.md +30 -0
  78. package/docs/ko/guide/getting-started.md +150 -0
  79. package/docs/ko/guide/glossary.md +214 -0
  80. package/docs/ko/guide/index.md +32 -0
  81. package/docs/ko/guide/ollama.md +410 -0
  82. package/docs/ko/guide/prompt-caching.md +221 -0
  83. package/docs/ko/guide/providers.md +232 -0
  84. package/docs/ko/guide/quality-control.md +137 -0
  85. package/docs/ko/guide/vitepress-integration.md +265 -0
  86. package/docs/ko/index.md +58 -0
  87. package/docs/zh/api/agent.md +262 -0
  88. package/docs/zh/api/engine.md +274 -0
  89. package/docs/zh/api/index.md +171 -0
  90. package/docs/zh/api/providers.md +304 -0
  91. package/docs/zh/changelog.md +64 -0
  92. package/docs/zh/cli/dir.md +243 -0
  93. package/docs/zh/cli/file.md +213 -0
  94. package/docs/zh/cli/glossary.md +273 -0
  95. package/docs/zh/cli/index.md +111 -0
  96. package/docs/zh/cli/init.md +158 -0
  97. package/docs/zh/guide/chunking.md +271 -0
  98. package/docs/zh/guide/configuration.md +139 -0
  99. package/docs/zh/guide/cost-optimization.md +30 -0
  100. package/docs/zh/guide/getting-started.md +150 -0
  101. package/docs/zh/guide/glossary.md +214 -0
  102. package/docs/zh/guide/index.md +32 -0
  103. package/docs/zh/guide/ollama.md +410 -0
  104. package/docs/zh/guide/prompt-caching.md +221 -0
  105. package/docs/zh/guide/providers.md +232 -0
  106. package/docs/zh/guide/quality-control.md +137 -0
  107. package/docs/zh/guide/vitepress-integration.md +265 -0
  108. package/docs/zh/index.md +58 -0
  109. package/package.json +91 -0
  110. package/release.config.mjs +15 -0
  111. package/schemas/glossary.schema.json +110 -0
  112. package/src/cli/commands/dir.ts +469 -0
  113. package/src/cli/commands/file.ts +291 -0
  114. package/src/cli/commands/glossary.ts +221 -0
  115. package/src/cli/commands/init.ts +68 -0
  116. package/src/cli/commands/serve.ts +60 -0
  117. package/src/cli/index.ts +64 -0
  118. package/src/cli/options.ts +59 -0
  119. package/src/core/agent.ts +1119 -0
  120. package/src/core/chunker.ts +391 -0
  121. package/src/core/engine.ts +634 -0
  122. package/src/errors.ts +188 -0
  123. package/src/index.ts +147 -0
  124. package/src/integrations/vitepress.ts +549 -0
  125. package/src/parsers/markdown.ts +383 -0
  126. package/src/providers/claude.ts +259 -0
  127. package/src/providers/interface.ts +109 -0
  128. package/src/providers/ollama.ts +379 -0
  129. package/src/providers/openai.ts +308 -0
  130. package/src/providers/registry.ts +153 -0
  131. package/src/server/index.ts +152 -0
  132. package/src/server/middleware/auth.ts +93 -0
  133. package/src/server/middleware/logger.ts +90 -0
  134. package/src/server/routes/health.ts +84 -0
  135. package/src/server/routes/translate.ts +210 -0
  136. package/src/server/types.ts +138 -0
  137. package/src/services/cache.ts +899 -0
  138. package/src/services/config.ts +217 -0
  139. package/src/services/glossary.ts +247 -0
  140. package/src/types/analysis.ts +164 -0
  141. package/src/types/index.ts +265 -0
  142. package/src/types/modes.ts +121 -0
  143. package/src/types/mqm.ts +157 -0
  144. package/src/utils/logger.ts +141 -0
  145. package/src/utils/tokens.ts +116 -0
  146. package/tests/fixtures/glossaries/ml-glossary.json +53 -0
  147. package/tests/fixtures/input/lynq-installation.ko.md +350 -0
  148. package/tests/fixtures/input/lynq-installation.md +350 -0
  149. package/tests/fixtures/input/simple.ko.md +27 -0
  150. package/tests/fixtures/input/simple.md +27 -0
  151. package/tests/unit/chunker.test.ts +229 -0
  152. package/tests/unit/glossary.test.ts +146 -0
  153. package/tests/unit/markdown.test.ts +205 -0
  154. package/tests/unit/tokens.test.ts +81 -0
  155. package/tsconfig.json +28 -0
  156. package/tsup.config.ts +34 -0
  157. package/vitest.config.ts +16 -0
package/docs/index.md ADDED
@@ -0,0 +1,63 @@
1
+ ---
2
+ layout: home
3
+
4
+ hero:
5
+ name: llm-translate
6
+ text: LLM-Powered Document Translation
7
+ tagline: Translate documents with glossary enforcement, quality control, and cost optimization
8
+ actions:
9
+ - theme: brand
10
+ text: Get Started
11
+ link: ./guide/getting-started
12
+ - theme: alt
13
+ text: View on GitHub
14
+ link: https://github.com/selenehyun/llm-translate
15
+
16
+ features:
17
+ - icon: 📚
18
+ title: Glossary Enforcement
19
+ details: Ensure consistent terminology across your translations with enforced glossary terms that never get mistranslated.
20
+ - icon: 🔄
21
+ title: Self-Refine Quality Control
22
+ details: Iterative translation refinement using AI-powered quality evaluation to meet your quality threshold.
23
+ - icon: 💰
24
+ title: Cost Optimization
25
+ details: Prompt caching reduces API costs by up to 90% for repeated content like glossaries and system prompts.
26
+ - icon: 🔌
27
+ title: Multi-Provider Support
28
+ details: Works with Claude, OpenAI, and Ollama. Switch providers without changing your workflow.
29
+ - icon: 📄
30
+ title: Format Preservation
31
+ details: Maintains markdown formatting, code blocks, links, and document structure during translation.
32
+ - icon: ⚡
33
+ title: Batch Processing
34
+ details: Translate entire directories with parallel processing and progress tracking.
35
+ ---
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ # Install globally
41
+ npm install -g @llm-translate/cli
42
+
43
+ # Set your API key
44
+ export ANTHROPIC_API_KEY=your-key-here
45
+
46
+ # Translate a file
47
+ llm-translate file README.md -o README.ko.md --target ko
48
+ ```
49
+
50
+ ## Why llm-translate?
51
+
52
+ Traditional translation tools struggle with technical documentation:
53
+
54
+ - **Inconsistent terminology** - "API endpoint" translated differently each time
55
+ - **Broken formatting** - Code blocks and markdown get mangled
56
+ - **No quality control** - Accept whatever the LLM outputs
57
+
58
+ llm-translate solves these problems with:
59
+
60
+ 1. **Glossary enforcement** - Define terms once, apply everywhere
61
+ 2. **AST-based chunking** - Preserves document structure
62
+ 3. **Quality-aware refinement** - Iterates until quality threshold is met
63
+ 4. **Prompt caching** - Reduces costs for large documents
@@ -0,0 +1,262 @@
1
+ # TranslationAgent
2
+
3
+ ::: info 翻訳について
4
+ 英語以外のドキュメントはすべてClaude Sonnet 4を使用して自動翻訳されています。
5
+ :::
6
+
7
+ Self-Refineアルゴリズムを実装した低レベル翻訳エージェントです。
8
+
9
+ ## コンストラクタ
10
+
11
+ ```typescript
12
+ import { TranslationAgent } from '@llm-translate/cli';
13
+
14
+ const agent = new TranslationAgent(options: TranslationAgentOptions);
15
+ ```
16
+
17
+ ### オプション
18
+
19
+ ```typescript
20
+ interface TranslationAgentOptions {
21
+ provider: LLMProvider;
22
+ qualityThreshold?: number; // Default: 85
23
+ maxIterations?: number; // Default: 4
24
+ verbose?: boolean; // Default: false
25
+ strictQuality?: boolean; // Default: false
26
+ enableCaching?: boolean; // Default: true for Claude
27
+ }
28
+ ```
29
+
30
+ ## メソッド
31
+
32
+ ### translate
33
+
34
+ Self-Refineループを使用してコンテンツを翻訳します。
35
+
36
+ ```typescript
37
+ const result = await agent.translate(request: TranslationRequest);
38
+ ```
39
+
40
+ #### リクエスト
41
+
42
+ ```typescript
43
+ interface TranslationRequest {
44
+ content: string; // Source text to translate
45
+ sourceLang: string; // Source language code
46
+ targetLang: string; // Target language code
47
+ glossary?: ResolvedGlossary; // Resolved glossary for target language
48
+ context?: {
49
+ documentPurpose?: string;
50
+ previousChunks?: string[];
51
+ documentSummary?: string;
52
+ };
53
+ }
54
+ ```
55
+
56
+ #### 結果
57
+
58
+ ```typescript
59
+ interface TranslationResult {
60
+ content: string; // Translated text
61
+ metadata: {
62
+ qualityScore: number;
63
+ qualityThreshold: number;
64
+ thresholdMet: boolean;
65
+ iterations: number;
66
+ tokensUsed: {
67
+ input: number;
68
+ output: number;
69
+ cacheRead?: number;
70
+ cacheWrite?: number;
71
+ };
72
+ duration: number;
73
+ provider: string;
74
+ model: string;
75
+ };
76
+ glossaryCompliance?: {
77
+ applied: string[]; // Terms successfully applied
78
+ missed: string[]; // Terms not found in translation
79
+ };
80
+ }
81
+ ```
82
+
83
+ ## Self-Refineアルゴリズム
84
+
85
+ エージェントは以下の反復的改善プロセスを実装しています:
86
+
87
+ ```typescript
88
+ // Pseudocode
89
+ async translate(request) {
90
+ // 1. Initial translation with glossary
91
+ let translation = await generateInitialTranslation(request);
92
+ let iterations = 1;
93
+
94
+ while (iterations < maxIterations) {
95
+ // 2. Evaluate quality
96
+ const evaluation = await evaluateQuality(translation);
97
+
98
+ if (evaluation.score >= qualityThreshold) {
99
+ break; // Quality met
100
+ }
101
+
102
+ // 3. Generate improvement suggestions
103
+ const suggestions = await generateReflection(translation);
104
+
105
+ // 4. Apply improvements
106
+ translation = await improveTranslation(translation, suggestions);
107
+ iterations++;
108
+ }
109
+
110
+ return { content: translation, metadata: { ... } };
111
+ }
112
+ ```
113
+
114
+ ## 使用例
115
+
116
+ ### 基本的な翻訳
117
+
118
+ ```typescript
119
+ import { TranslationAgent, createClaudeProvider } from '@llm-translate/cli';
120
+
121
+ const provider = createClaudeProvider();
122
+ const agent = new TranslationAgent({
123
+ provider,
124
+ qualityThreshold: 85,
125
+ });
126
+
127
+ const result = await agent.translate({
128
+ content: 'Hello, world!',
129
+ sourceLang: 'en',
130
+ targetLang: 'ko',
131
+ });
132
+
133
+ console.log(result.content); // 안녕하세요, 세계!
134
+ console.log(result.metadata.qualityScore); // 92
135
+ ```
136
+
137
+ ### 用語集を使用した翻訳
138
+
139
+ ```typescript
140
+ import { loadGlossary, resolveGlossary } from '@llm-translate/cli';
141
+
142
+ const glossary = await loadGlossary('./glossary.json');
143
+ const resolved = resolveGlossary(glossary, 'ko');
144
+
145
+ const result = await agent.translate({
146
+ content: 'The component renders a prop.',
147
+ sourceLang: 'en',
148
+ targetLang: 'ko',
149
+ glossary: resolved,
150
+ });
151
+
152
+ console.log(result.glossaryCompliance);
153
+ // { applied: ['component', 'prop'], missed: [] }
154
+ ```
155
+
156
+ ### コンテキストを使用した翻訳
157
+
158
+ ```typescript
159
+ const result = await agent.translate({
160
+ content: 'Click the button to continue.',
161
+ sourceLang: 'en',
162
+ targetLang: 'ko',
163
+ context: {
164
+ documentPurpose: 'User interface instructions',
165
+ previousChunks: [
166
+ '이전 단계에서 설정을 완료했습니다.', // Previous translation
167
+ ],
168
+ },
169
+ });
170
+ ```
171
+
172
+ ### 厳格品質モード
173
+
174
+ ```typescript
175
+ import { TranslationError, ErrorCode } from '@llm-translate/cli';
176
+
177
+ const agent = new TranslationAgent({
178
+ provider,
179
+ qualityThreshold: 95,
180
+ strictQuality: true, // Throw if threshold not met
181
+ });
182
+
183
+ try {
184
+ const result = await agent.translate(request);
185
+ } catch (error) {
186
+ if (error instanceof TranslationError &&
187
+ error.code === ErrorCode.QUALITY_THRESHOLD_NOT_MET) {
188
+ console.log(`Quality: ${error.details.score}/${error.details.threshold}`);
189
+ console.log(`Issues: ${error.details.issues.join(', ')}`);
190
+ }
191
+ }
192
+ ```
193
+
194
+ ## 品質評価
195
+
196
+ エージェントは4つの基準で翻訳を評価します:
197
+
198
+ | 基準 | 重み | 説明 |
199
+ |-----------|--------|-------------|
200
+ | 意味の正確性 | 40% | 意味の保持 |
201
+ | 流暢性 | 25% | 自然な言語の流れ |
202
+ | 用語集の遵守 | 20% | 用語の一貫性 |
203
+ | 形式の保持 | 15% | 構造の維持 |
204
+
205
+ ### 評価結果
206
+
207
+ ```typescript
208
+ interface QualityEvaluation {
209
+ score: number; // 0-100
210
+ breakdown: {
211
+ accuracy: number; // 0-40
212
+ fluency: number; // 0-25
213
+ glossary: number; // 0-20
214
+ format: number; // 0-15
215
+ };
216
+ issues: string[]; // Specific problems identified
217
+ }
218
+ ```
219
+
220
+ ## プロンプトキャッシング
221
+
222
+ `enableCaching` がtrue(Claudeのデフォルト)の場合、エージェントはキャッシング用にプロンプトを構造化します:
223
+
224
+ ```
225
+ ┌─────────────────────────────────┐
226
+ │ System Instructions (CACHED) │ ← Reused across chunks
227
+ ├─────────────────────────────────┤
228
+ │ Glossary (CACHED) │ ← Reused across chunks
229
+ ├─────────────────────────────────┤
230
+ │ Source Text (NOT cached) │ ← Changes per chunk
231
+ └─────────────────────────────────┘
232
+ ```
233
+
234
+ これにより、マルチチャンクドキュメントのコストを40-50%削減できます。
235
+
236
+ ## 高度な使用法:カスタム評価
237
+
238
+ デフォルトの評価ロジックをオーバーライドします:
239
+
240
+ ```typescript
241
+ class CustomAgent extends TranslationAgent {
242
+ protected async evaluateQuality(
243
+ source: string,
244
+ translation: string,
245
+ sourceLang: string,
246
+ targetLang: string
247
+ ): Promise<QualityEvaluation> {
248
+ // Custom evaluation logic
249
+ const baseEval = await super.evaluateQuality(
250
+ source, translation, sourceLang, targetLang
251
+ );
252
+
253
+ // Add custom checks
254
+ if (translation.length < source.length * 0.5) {
255
+ baseEval.score -= 10;
256
+ baseEval.issues.push('Translation suspiciously short');
257
+ }
258
+
259
+ return baseEval;
260
+ }
261
+ }
262
+ ```
@@ -0,0 +1,274 @@
1
+ # TranslationEngine
2
+
3
+ ::: info 翻訳について
4
+ 英語以外のドキュメントはすべてClaude Sonnet 4を使用して自動翻訳されています。
5
+ :::
6
+
7
+ 翻訳操作のメインエントリーポイントです。
8
+
9
+ ## コンストラクタ
10
+
11
+ ```typescript
12
+ import { TranslationEngine } from '@llm-translate/cli';
13
+
14
+ const engine = new TranslationEngine(options: TranslationEngineOptions);
15
+ ```
16
+
17
+ ### オプション
18
+
19
+ ```typescript
20
+ interface TranslationEngineOptions {
21
+ provider: LLMProvider;
22
+ qualityThreshold?: number; // Default: 85
23
+ maxIterations?: number; // Default: 4
24
+ chunkingConfig?: ChunkingConfig;
25
+ verbose?: boolean; // Default: false
26
+ }
27
+ ```
28
+
29
+ ## メソッド
30
+
31
+ ### translateFile
32
+
33
+ 単一ファイルを翻訳します。
34
+
35
+ ```typescript
36
+ const result = await engine.translateFile(options: TranslateFileOptions);
37
+ ```
38
+
39
+ #### オプション
40
+
41
+ ```typescript
42
+ interface TranslateFileOptions {
43
+ input: string; // Input file path
44
+ output?: string; // Output file path (optional)
45
+ sourceLang?: string; // Source language (auto-detect if omitted)
46
+ targetLang: string; // Target language (required)
47
+ glossary?: string | Glossary; // Glossary path or object
48
+ context?: {
49
+ documentPurpose?: string;
50
+ preserveFormatting?: boolean;
51
+ };
52
+ }
53
+ ```
54
+
55
+ #### 戻り値
56
+
57
+ ```typescript
58
+ interface TranslateFileResult {
59
+ content: string;
60
+ outputPath?: string;
61
+ metadata: {
62
+ qualityScore: number;
63
+ qualityThreshold: number;
64
+ thresholdMet: boolean;
65
+ iterations: number;
66
+ tokensUsed: {
67
+ input: number;
68
+ output: number;
69
+ cacheRead?: number;
70
+ cacheWrite?: number;
71
+ };
72
+ duration: number;
73
+ chunks: number;
74
+ };
75
+ }
76
+ ```
77
+
78
+ #### 例
79
+
80
+ ```typescript
81
+ const result = await engine.translateFile({
82
+ input: 'docs/guide.md',
83
+ output: 'docs/guide.ko.md',
84
+ targetLang: 'ko',
85
+ glossary: './glossary.json',
86
+ context: {
87
+ documentPurpose: 'Technical documentation for developers',
88
+ },
89
+ });
90
+
91
+ console.log(`Quality: ${result.metadata.qualityScore}`);
92
+ console.log(`Output: ${result.outputPath}`);
93
+ ```
94
+
95
+ ### translateContent
96
+
97
+ コンテンツを直接翻訳します(ファイルI/Oなし)。
98
+
99
+ ```typescript
100
+ const result = await engine.translateContent(
101
+ content: string,
102
+ options: TranslateContentOptions
103
+ );
104
+ ```
105
+
106
+ #### オプション
107
+
108
+ ```typescript
109
+ interface TranslateContentOptions {
110
+ sourceLang?: string;
111
+ targetLang: string;
112
+ glossary?: ResolvedGlossary;
113
+ format?: 'markdown' | 'html' | 'text';
114
+ context?: {
115
+ documentPurpose?: string;
116
+ previousChunks?: string[];
117
+ };
118
+ }
119
+ ```
120
+
121
+ #### 例
122
+
123
+ ```typescript
124
+ const content = `
125
+ # Hello World
126
+
127
+ This is a **markdown** document.
128
+ `;
129
+
130
+ const result = await engine.translateContent(content, {
131
+ targetLang: 'ko',
132
+ format: 'markdown',
133
+ });
134
+
135
+ console.log(result.content);
136
+ // # 안녕하세요
137
+ //
138
+ // 이것은 **마크다운** 문서입니다.
139
+ ```
140
+
141
+ ### translateDirectory
142
+
143
+ ディレクトリ内のすべてのファイルを翻訳します。
144
+
145
+ ```typescript
146
+ const results = await engine.translateDirectory(options: TranslateDirectoryOptions);
147
+ ```
148
+
149
+ #### オプション
150
+
151
+ ```typescript
152
+ interface TranslateDirectoryOptions {
153
+ input: string; // Input directory
154
+ output: string; // Output directory
155
+ targetLang: string;
156
+ glossary?: string | Glossary;
157
+ pattern?: string; // Glob pattern (default: '**/*.md')
158
+ exclude?: string[]; // Patterns to exclude
159
+ concurrency?: number; // Parallel processing (default: 3)
160
+ continueOnError?: boolean;
161
+ }
162
+ ```
163
+
164
+ #### 戻り値
165
+
166
+ ```typescript
167
+ interface TranslateDirectoryResult {
168
+ successful: TranslateFileResult[];
169
+ failed: Array<{
170
+ file: string;
171
+ error: Error;
172
+ }>;
173
+ summary: {
174
+ total: number;
175
+ successful: number;
176
+ failed: number;
177
+ totalDuration: number;
178
+ averageQuality: number;
179
+ };
180
+ }
181
+ ```
182
+
183
+ #### 例
184
+
185
+ ```typescript
186
+ const results = await engine.translateDirectory({
187
+ input: './docs',
188
+ output: './docs-ko',
189
+ targetLang: 'ko',
190
+ glossary: './glossary.json',
191
+ concurrency: 5,
192
+ continueOnError: true,
193
+ });
194
+
195
+ console.log(`Translated: ${results.summary.successful}/${results.summary.total}`);
196
+ console.log(`Average quality: ${results.summary.averageQuality}`);
197
+ ```
198
+
199
+ ## イベント
200
+
201
+ TranslationEngineはEventEmitterを継承しています:
202
+
203
+ ```typescript
204
+ engine.on('chunk:start', (data) => {
205
+ console.log(`Starting chunk ${data.index}/${data.total}`);
206
+ });
207
+
208
+ engine.on('chunk:complete', (data) => {
209
+ console.log(`Chunk ${data.index}: quality ${data.quality}`);
210
+ });
211
+
212
+ engine.on('file:start', (data) => {
213
+ console.log(`Translating: ${data.file}`);
214
+ });
215
+
216
+ engine.on('file:complete', (data) => {
217
+ console.log(`Completed: ${data.file} (${data.quality})`);
218
+ });
219
+ ```
220
+
221
+ ## 完全な例
222
+
223
+ ```typescript
224
+ import {
225
+ TranslationEngine,
226
+ createClaudeProvider,
227
+ loadGlossary,
228
+ resolveGlossary,
229
+ } from '@llm-translate/cli';
230
+
231
+ async function translateDocs() {
232
+ // Setup provider
233
+ const provider = createClaudeProvider({
234
+ apiKey: process.env.ANTHROPIC_API_KEY,
235
+ defaultModel: 'claude-sonnet-4-5-20250929',
236
+ });
237
+
238
+ // Load and resolve glossary
239
+ const glossary = await loadGlossary('./glossary.json');
240
+
241
+ // Create engine
242
+ const engine = new TranslationEngine({
243
+ provider,
244
+ qualityThreshold: 90,
245
+ maxIterations: 5,
246
+ verbose: true,
247
+ });
248
+
249
+ // Track progress
250
+ engine.on('chunk:complete', ({ index, total, quality }) => {
251
+ console.log(`Progress: ${index}/${total} (quality: ${quality})`);
252
+ });
253
+
254
+ // Translate
255
+ try {
256
+ const result = await engine.translateFile({
257
+ input: 'README.md',
258
+ output: 'README.ko.md',
259
+ targetLang: 'ko',
260
+ glossary,
261
+ });
262
+
263
+ console.log('Translation complete!');
264
+ console.log(`Quality: ${result.metadata.qualityScore}`);
265
+ console.log(`Tokens: ${result.metadata.tokensUsed.input} in / ${result.metadata.tokensUsed.output} out`);
266
+
267
+ if (result.metadata.tokensUsed.cacheRead) {
268
+ console.log(`Cache hit: ${result.metadata.tokensUsed.cacheRead} tokens`);
269
+ }
270
+ } catch (error) {
271
+ console.error('Translation failed:', error.message);
272
+ }
273
+ }
274
+ ```