@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,274 @@
1
+ # TranslationEngine
2
+
3
+ ::: info Translations
4
+ All non-English documentation is automatically translated using Claude Sonnet 4.
5
+ :::
6
+
7
+ The main entry point for translation operations.
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
+ Translate a single file.
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
+ Translate content directly (without file 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
+ Translate all files in a directory.
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 extends 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 Translations
4
+ All non-English documentation is automatically translated using Claude Sonnet 4.
5
+ :::
6
+
7
+ llm-translate can be used programmatically in your Node.js applications.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @llm-translate/cli
13
+ ```
14
+
15
+ ## Quick Start
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
+ ## Core Classes
43
+
44
+ ### [TranslationEngine](./engine)
45
+
46
+ Main entry point for translation operations.
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
+ Low-level translation agent with Self-Refine loop.
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 provider implementations.
66
+
67
+ ```typescript
68
+ import {
69
+ createClaudeProvider,
70
+ createOpenAIProvider,
71
+ createOllamaProvider,
72
+ } from '@llm-translate/cli';
73
+ ```
74
+
75
+ ## Type Exports
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
+ ## Utility Functions
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
+ ### Glossary
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
+ ### Token Estimation
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
+ ## Error Handling
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
+ ## Error Codes
160
+
161
+ | Code | Description |
162
+ |------|-------------|
163
+ | `FILE_NOT_FOUND` | Input file does not exist |
164
+ | `INVALID_CONFIG` | Configuration validation failed |
165
+ | `GLOSSARY_NOT_FOUND` | Glossary file not found |
166
+ | `GLOSSARY_INVALID` | Glossary validation failed |
167
+ | `PROVIDER_AUTH_FAILED` | API key invalid |
168
+ | `PROVIDER_RATE_LIMITED` | Rate limit exceeded |
169
+ | `PROVIDER_ERROR` | General provider error |
170
+ | `QUALITY_THRESHOLD_NOT_MET` | Translation quality below threshold |
171
+ | `PARSE_ERROR` | Document parsing failed |