@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
@@ -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
+ 에이전트는 네 가지 기준으로 번역을 평가합니다:
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
+ ## Constructor
10
+
11
+ ```typescript
12
+ import { TranslationEngine } from '@llm-translate/cli';
13
+
14
+ const engine = new TranslationEngine(options: TranslationEngineOptions);
15
+ ```
16
+
17
+ ### Options
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
+ ## Methods
30
+
31
+ ### translateFile
32
+
33
+ 단일 파일을 번역합니다.
34
+
35
+ ```typescript
36
+ const result = await engine.translateFile(options: TranslateFileOptions);
37
+ ```
38
+
39
+ #### Options
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
+ #### Returns
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
+ #### Example
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
+ #### Options
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
+ #### Example
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
+ #### Options
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
+ #### Returns
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
+ #### Example
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
+ ## Events
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
+ ## Full Example
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
+ ```
@@ -0,0 +1,171 @@
1
+ # API Reference
2
+
3
+ ::: info 번역
4
+ 모든 비영어 문서는 Claude Sonnet 4를 사용하여 자동으로 번역됩니다.
5
+ :::
6
+
7
+ llm-translate는 Node.js 애플리케이션에서 프로그래밍 방식으로 사용할 수 있습니다.
8
+
9
+ ## 설치
10
+
11
+ ```bash
12
+ npm install @llm-translate/cli
13
+ ```
14
+
15
+ ## 빠른 시작
16
+
17
+ ```typescript
18
+ import { TranslationEngine, createClaudeProvider } from '@llm-translate/cli';
19
+
20
+ // Create provider
21
+ const provider = createClaudeProvider({
22
+ apiKey: process.env.ANTHROPIC_API_KEY,
23
+ });
24
+
25
+ // Create engine
26
+ const engine = new TranslationEngine({
27
+ provider,
28
+ qualityThreshold: 85,
29
+ });
30
+
31
+ // Translate
32
+ const result = await engine.translateFile({
33
+ input: 'README.md',
34
+ output: 'README.ko.md',
35
+ sourceLang: 'en',
36
+ targetLang: 'ko',
37
+ });
38
+
39
+ console.log(result.metadata);
40
+ ```
41
+
42
+ ## 핵심 클래스
43
+
44
+ ### [TranslationEngine](./engine)
45
+
46
+ 번역 작업의 주요 진입점입니다.
47
+
48
+ ```typescript
49
+ const engine = new TranslationEngine(options);
50
+ await engine.translateFile({ input, output, targetLang });
51
+ await engine.translateContent(content, options);
52
+ ```
53
+
54
+ ### [TranslationAgent](./agent)
55
+
56
+ Self-Refine 루프를 가진 저수준 번역 에이전트입니다.
57
+
58
+ ```typescript
59
+ const agent = new TranslationAgent({ provider, qualityThreshold });
60
+ const result = await agent.translate(request);
61
+ ```
62
+
63
+ ### [Providers](./providers)
64
+
65
+ LLM 제공자 구현체입니다.
66
+
67
+ ```typescript
68
+ import {
69
+ createClaudeProvider,
70
+ createOpenAIProvider,
71
+ createOllamaProvider,
72
+ } from '@llm-translate/cli';
73
+ ```
74
+
75
+ ## 타입 내보내기
76
+
77
+ ```typescript
78
+ import type {
79
+ // Configuration
80
+ TranslationConfig,
81
+ ProviderConfig,
82
+
83
+ // Requests/Results
84
+ TranslationRequest,
85
+ TranslationResult,
86
+
87
+ // Glossary
88
+ Glossary,
89
+ GlossaryTerm,
90
+ ResolvedGlossary,
91
+
92
+ // Quality
93
+ QualityEvaluation,
94
+
95
+ // Provider
96
+ LLMProvider,
97
+ ChatMessage,
98
+ ChatResponse,
99
+ } from '@llm-translate/cli';
100
+ ```
101
+
102
+ ## 유틸리티 함수
103
+
104
+ ### Chunking
105
+
106
+ ```typescript
107
+ import { chunkContent, chunkMarkdown } from '@llm-translate/cli';
108
+
109
+ const chunks = chunkContent(text, { maxTokens: 1024 });
110
+ const mdChunks = chunkMarkdown(markdown, { maxTokens: 1024 });
111
+ ```
112
+
113
+ ### 용어집
114
+
115
+ ```typescript
116
+ import { loadGlossary, resolveGlossary, createGlossaryLookup } from '@llm-translate/cli';
117
+
118
+ const glossary = await loadGlossary('./glossary.json');
119
+ const resolved = resolveGlossary(glossary, 'ko');
120
+ const lookup = createGlossaryLookup(resolved);
121
+
122
+ const terms = lookup.findAll(sourceText);
123
+ ```
124
+
125
+ ### 토큰 추정
126
+
127
+ ```typescript
128
+ import { estimateTokens, calculateTokenBudget } from '@llm-translate/cli';
129
+
130
+ const tokens = estimateTokens(text);
131
+ const budget = calculateTokenBudget(text, { glossaryTokens: 500 });
132
+ ```
133
+
134
+ ## 오류 처리
135
+
136
+ ```typescript
137
+ import { TranslationError, ErrorCode } from '@llm-translate/cli';
138
+
139
+ try {
140
+ await engine.translateFile(options);
141
+ } catch (error) {
142
+ if (error instanceof TranslationError) {
143
+ switch (error.code) {
144
+ case ErrorCode.FILE_NOT_FOUND:
145
+ // Handle missing file
146
+ break;
147
+ case ErrorCode.QUALITY_THRESHOLD_NOT_MET:
148
+ // Handle quality issue
149
+ console.log('Score:', error.details.score);
150
+ break;
151
+ case ErrorCode.PROVIDER_RATE_LIMITED:
152
+ // Handle rate limit
153
+ break;
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ ## 오류 코드
160
+
161
+ | 코드 | 설명 |
162
+ |------|-------------|
163
+ |`FILE_NOT_FOUND`| 입력 파일이 존재하지 않습니다 |
164
+ |`INVALID_CONFIG`| 구성 검증에 실패했습니다 |
165
+ |`GLOSSARY_NOT_FOUND`| 용어집 파일을 찾을 수 없습니다 |
166
+ |`GLOSSARY_INVALID`| 용어집 검증에 실패했습니다 |
167
+ |`PROVIDER_AUTH_FAILED`| API 키가 유효하지 않습니다 |
168
+ |`PROVIDER_RATE_LIMITED`| 속도 제한을 초과했습니다 |
169
+ |`PROVIDER_ERROR`| 일반적인 제공자 오류입니다 |
170
+ |`QUALITY_THRESHOLD_NOT_MET`| 번역 품질이 임계값 미만입니다 |
171
+ |`PARSE_ERROR`| 문서 파싱에 실패했습니다 |