@geolonia/yuuhitsu 0.1.0 → 0.1.2

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 (73) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +114 -0
  3. package/dist/cli/commands/glossary.d.ts +3 -0
  4. package/dist/cli/commands/glossary.d.ts.map +1 -0
  5. package/dist/cli/commands/glossary.js +110 -0
  6. package/dist/cli/commands/glossary.js.map +1 -0
  7. package/dist/cli/commands/init.d.ts +3 -0
  8. package/dist/cli/commands/init.d.ts.map +1 -0
  9. package/dist/cli/commands/init.js +82 -0
  10. package/dist/cli/commands/init.js.map +1 -0
  11. package/dist/cli/commands/translate.d.ts +0 -0
  12. package/dist/cli/commands/translate.d.ts.map +1 -1
  13. package/dist/cli/commands/translate.js +53 -26
  14. package/dist/cli/commands/translate.js.map +1 -1
  15. package/dist/cli/index.d.ts +0 -0
  16. package/dist/cli/index.d.ts.map +1 -1
  17. package/dist/cli/index.js +4 -0
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/config.d.ts +1 -0
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +6 -0
  22. package/dist/config.js.map +1 -1
  23. package/dist/errors.d.ts +0 -0
  24. package/dist/errors.d.ts.map +0 -0
  25. package/dist/errors.js +0 -0
  26. package/dist/errors.js.map +0 -0
  27. package/dist/logger.d.ts +0 -0
  28. package/dist/logger.d.ts.map +0 -0
  29. package/dist/logger.js +0 -0
  30. package/dist/logger.js.map +0 -0
  31. package/dist/provider/claude.d.ts +0 -0
  32. package/dist/provider/claude.d.ts.map +0 -0
  33. package/dist/provider/claude.js +0 -0
  34. package/dist/provider/claude.js.map +0 -0
  35. package/dist/provider/gemini.d.ts +0 -0
  36. package/dist/provider/gemini.d.ts.map +0 -0
  37. package/dist/provider/gemini.js +0 -0
  38. package/dist/provider/gemini.js.map +0 -0
  39. package/dist/provider/index.d.ts +0 -0
  40. package/dist/provider/index.d.ts.map +0 -0
  41. package/dist/provider/index.js +0 -0
  42. package/dist/provider/index.js.map +0 -0
  43. package/dist/provider/interface.d.ts +0 -0
  44. package/dist/provider/interface.d.ts.map +0 -0
  45. package/dist/provider/interface.js +0 -0
  46. package/dist/provider/interface.js.map +0 -0
  47. package/dist/provider/ollama.d.ts +0 -0
  48. package/dist/provider/ollama.d.ts.map +0 -0
  49. package/dist/provider/ollama.js +0 -0
  50. package/dist/provider/ollama.js.map +0 -0
  51. package/dist/tasks/batch-translate.d.ts +46 -0
  52. package/dist/tasks/batch-translate.d.ts.map +1 -0
  53. package/dist/tasks/batch-translate.js +174 -0
  54. package/dist/tasks/batch-translate.js.map +1 -0
  55. package/dist/tasks/glossary.d.ts +41 -0
  56. package/dist/tasks/glossary.d.ts.map +1 -0
  57. package/dist/tasks/glossary.js +273 -0
  58. package/dist/tasks/glossary.js.map +1 -0
  59. package/dist/tasks/stream.d.ts +0 -0
  60. package/dist/tasks/stream.d.ts.map +0 -0
  61. package/dist/tasks/stream.js +0 -0
  62. package/dist/tasks/stream.js.map +0 -0
  63. package/dist/tasks/translate.d.ts +27 -0
  64. package/dist/tasks/translate.d.ts.map +1 -1
  65. package/dist/tasks/translate.js +101 -7
  66. package/dist/tasks/translate.js.map +1 -1
  67. package/package.json +14 -8
  68. package/src/templates/fix-links.md +0 -0
  69. package/src/templates/generate-docs.md +0 -0
  70. package/src/templates/generate-tests.md +0 -0
  71. package/src/templates/research.md +0 -0
  72. package/src/templates/sync-docs.md +0 -0
  73. package/src/templates/translate.md +8 -0
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -9,6 +9,7 @@ AI-powered document operations CLI
9
9
  ### Key Capabilities
10
10
 
11
11
  - **Markdown Translation**: Translate documents while preserving structure, code blocks, and formatting
12
+ - **Glossary Management**: Maintain consistent terminology across all translations with a project-level glossary
12
13
  - **Multi-Provider Support**: Switch between Claude (Anthropic), Gemini (Google), and Ollama (local) with a single config line change
13
14
  - **Streaming Output**: See translation progress in real-time
14
15
  - **Dry-Run Mode**: Preview operations without making API calls
@@ -23,6 +24,18 @@ AI-powered document operations CLI
23
24
  - Support for large files with automatic chunking
24
25
  - Real-time streaming output
25
26
  - Retry logic with exponential backoff for API failures
27
+ - Automatic glossary lookup during translation (when `glossary` is configured)
28
+
29
+ ### Glossary Management (Available Now)
30
+
31
+ Maintain a project-level glossary to enforce consistent terminology across all translations.
32
+
33
+ - **`glossary init`**: Generate a `glossary.yaml` skeleton with example terms
34
+ - **`glossary check`**: Detect forbidden or inconsistent terms in a document
35
+ - **`glossary sync`**: Report translation coverage across all configured languages and create stubs for missing entries
36
+ - **`glossary review`**: Generate a Markdown report of all glossary terms and their translations
37
+
38
+ When a `glossary` path is set in `yuuhitsu.config.yaml`, the `translate` command automatically injects the glossary into the AI prompt, ensuring canonical terms are used and forbidden variants are avoided.
26
39
 
27
40
  ### Coming Soon
28
41
 
@@ -68,6 +81,7 @@ model: claude-sonnet-4-5-20250929
68
81
  # Optional Settings
69
82
  outputDir: ./translated
70
83
  templates: ./templates
84
+ glossary: ./glossary.yaml # Path to glossary file (enables auto-injection during translation)
71
85
  log:
72
86
  enabled: true
73
87
  path: ./yuuhitsu.log
@@ -124,6 +138,106 @@ yuuhitsu translate \
124
138
  --model claude-sonnet-4-5-20250929
125
139
  ```
126
140
 
141
+ ### `glossary`
142
+
143
+ Manage the project glossary for terminology consistency.
144
+
145
+ #### `glossary init`
146
+
147
+ Generate a `glossary.yaml` skeleton in the current directory.
148
+
149
+ **Options:**
150
+
151
+ - `--output <path>`: Output path for the glossary file (default: `glossary.yaml`)
152
+ - `--force`: Overwrite an existing glossary file
153
+
154
+ **Example:**
155
+
156
+ ```bash
157
+ yuuhitsu glossary init
158
+ yuuhitsu glossary init --output ./docs/glossary.yaml
159
+ ```
160
+
161
+ #### `glossary check`
162
+
163
+ Detect forbidden or inconsistent terminology in a document.
164
+
165
+ **Options:**
166
+
167
+ - `--input <file>` (required): Document file to check
168
+ - `--glossary <path>` (required): Glossary file path
169
+ - `--lang <code>` (required): Language code to check (e.g., `ja`, `en`)
170
+
171
+ **Example:**
172
+
173
+ ```bash
174
+ yuuhitsu glossary check --input README.md --glossary glossary.yaml --lang ja
175
+ ```
176
+
177
+ #### `glossary sync`
178
+
179
+ Report translation coverage and create stubs for missing entries.
180
+
181
+ **Options:**
182
+
183
+ - `--glossary <path>` (required): Glossary file path
184
+
185
+ **Example:**
186
+
187
+ ```bash
188
+ yuuhitsu glossary sync --glossary glossary.yaml
189
+ ```
190
+
191
+ #### `glossary review`
192
+
193
+ Generate a Markdown report of all glossary terms and their translations.
194
+
195
+ **Options:**
196
+
197
+ - `--glossary <path>` (required): Glossary file path
198
+ - `--output <path>`: Save the report to a file (Markdown)
199
+
200
+ **Example:**
201
+
202
+ ```bash
203
+ yuuhitsu glossary review --glossary glossary.yaml
204
+ yuuhitsu glossary review --glossary glossary.yaml --output glossary-report.md
205
+ ```
206
+
207
+ ### Glossary File Format
208
+
209
+ The `glossary.yaml` file defines canonical terms, their translations, and forbidden variants:
210
+
211
+ ```yaml
212
+ version: 1
213
+ languages: [ja, en]
214
+ terms:
215
+ - canonical: "API"
216
+ type: noun
217
+ translations:
218
+ ja: "API"
219
+ en: "API"
220
+ do_not_use:
221
+ ja: ["API", "えーぴーあい"]
222
+ - canonical: "webhook"
223
+ type: noun
224
+ translations:
225
+ ja: "Webhook"
226
+ en: "webhook"
227
+ do_not_use:
228
+ ja: ["ウェブフック"]
229
+ en: ["web hook"]
230
+ ```
231
+
232
+ | Field | Description |
233
+ |-------|-------------|
234
+ | `version` | Schema version (currently `1`) |
235
+ | `languages` | List of language codes managed by this glossary |
236
+ | `terms[].canonical` | The authoritative (source-language) term |
237
+ | `terms[].type` | Term type (e.g., `noun`, `verb`) |
238
+ | `terms[].translations` | Map of language code → translated term |
239
+ | `terms[].do_not_use` | Map of language code → list of forbidden variants |
240
+
127
241
  ## Development
128
242
 
129
243
  ```bash
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const glossaryCommand: Command;
3
+ //# sourceMappingURL=glossary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/glossary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0IpC,eAAO,MAAM,eAAe,SAKJ,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { Command } from "commander";
2
+ import { writeFileSync } from "fs";
3
+ import { resolve } from "path";
4
+ import chalk from "chalk";
5
+ import { initGlossary, checkGlossary, syncGlossary, reviewGlossary, } from "../../tasks/glossary.js";
6
+ import { formatError } from "../../errors.js";
7
+ // ---------------------------------------------------------------------------
8
+ // glossary init
9
+ // ---------------------------------------------------------------------------
10
+ const initCmd = new Command("init")
11
+ .description("Generate a glossary.yaml skeleton")
12
+ .option("--output <path>", "Output path for glossary file", "glossary.yaml")
13
+ .option("--force", "Overwrite existing glossary file")
14
+ .action(async (opts) => {
15
+ const outputPath = resolve(process.cwd(), opts.output);
16
+ try {
17
+ initGlossary(outputPath, opts.force || undefined);
18
+ process.stdout.write(`${chalk.green("✓")} Glossary file created: ${outputPath}\n`);
19
+ }
20
+ catch (err) {
21
+ process.stderr.write(formatError(err) + "\n");
22
+ process.exit(1);
23
+ }
24
+ });
25
+ // ---------------------------------------------------------------------------
26
+ // glossary check
27
+ // ---------------------------------------------------------------------------
28
+ const checkCmd = new Command("check")
29
+ .description("Detect terminology inconsistencies in a document")
30
+ .requiredOption("--input <file>", "Document file to check")
31
+ .requiredOption("--glossary <path>", "Glossary file path")
32
+ .requiredOption("--lang <code>", "Language code to check (e.g., ja, en)")
33
+ .action(async (opts) => {
34
+ try {
35
+ const issues = checkGlossary(opts.input, opts.glossary, opts.lang);
36
+ if (issues.length === 0) {
37
+ process.stdout.write(`${chalk.green("✓")} No issues found in ${opts.input}\n`);
38
+ return;
39
+ }
40
+ process.stdout.write(`${chalk.yellow("⚠")} Found ${issues.length} terminology issue(s) in ${opts.input}:\n\n`);
41
+ for (const issue of issues) {
42
+ process.stdout.write(` Line ${issue.line}: "${chalk.red(issue.forbidden)}" → use "${chalk.green(issue.canonical)}"\n`);
43
+ }
44
+ process.exit(1);
45
+ }
46
+ catch (err) {
47
+ process.stderr.write(formatError(err) + "\n");
48
+ process.exit(1);
49
+ }
50
+ });
51
+ // ---------------------------------------------------------------------------
52
+ // glossary sync
53
+ // ---------------------------------------------------------------------------
54
+ const syncCmd = new Command("sync")
55
+ .description("Sync glossary with translation files and report coverage")
56
+ .requiredOption("--glossary <path>", "Glossary file path")
57
+ .action(async (opts) => {
58
+ try {
59
+ const result = syncGlossary(opts.glossary);
60
+ process.stdout.write(`${chalk.green("✓")} Glossary sync report\n\n` +
61
+ ` Total terms: ${result.totalTerms}\n`);
62
+ for (const [lang, terms] of Object.entries(result.termsByLanguage)) {
63
+ process.stdout.write(` ${lang}: ${terms.length} / ${result.totalTerms} terms translated\n`);
64
+ }
65
+ if (result.missingTranslations.length > 0) {
66
+ process.stdout.write(`\n${chalk.yellow("⚠")} Missing translations:\n`);
67
+ for (const missing of result.missingTranslations) {
68
+ process.stdout.write(` "${missing.canonical}" missing: ${missing.missingLanguages.join(", ")}\n`);
69
+ }
70
+ }
71
+ }
72
+ catch (err) {
73
+ process.stderr.write(formatError(err) + "\n");
74
+ process.exit(1);
75
+ }
76
+ });
77
+ // ---------------------------------------------------------------------------
78
+ // glossary review
79
+ // ---------------------------------------------------------------------------
80
+ const reviewCmd = new Command("review")
81
+ .description("Generate a glossary review report")
82
+ .requiredOption("--glossary <path>", "Glossary file path")
83
+ .option("--output <path>", "Save report to file (Markdown)")
84
+ .action(async (opts) => {
85
+ try {
86
+ const report = reviewGlossary(opts.glossary);
87
+ const markdown = report.toMarkdown();
88
+ if (opts.output) {
89
+ writeFileSync(opts.output, markdown, "utf-8");
90
+ process.stdout.write(`${chalk.green("✓")} Review report saved to ${opts.output}\n`);
91
+ }
92
+ else {
93
+ process.stdout.write(markdown);
94
+ }
95
+ }
96
+ catch (err) {
97
+ process.stderr.write(formatError(err) + "\n");
98
+ process.exit(1);
99
+ }
100
+ });
101
+ // ---------------------------------------------------------------------------
102
+ // glossary (parent command)
103
+ // ---------------------------------------------------------------------------
104
+ export const glossaryCommand = new Command("glossary")
105
+ .description("Manage glossary for terminology consistency")
106
+ .addCommand(initCmd)
107
+ .addCommand(checkCmd)
108
+ .addCommand(syncCmd)
109
+ .addCommand(reviewCmd);
110
+ //# sourceMappingURL=glossary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../../src/cli/commands/glossary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const initCommand: Command;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiDpC,eAAO,MAAM,WAAW,SA6CpB,CAAC"}
@@ -0,0 +1,82 @@
1
+ import { Command } from "commander";
2
+ import { writeFileSync, existsSync } from "fs";
3
+ import { join } from "path";
4
+ import chalk from "chalk";
5
+ const DEFAULT_CONFIG_TEMPLATE = `# Yuuhitsu Configuration File
6
+ # AI-powered document operations CLI
7
+ # See: https://github.com/geolonia/yuuhitsu
8
+
9
+ # AI Provider Selection
10
+ # Choose one: claude, gemini, or ollama
11
+ provider: claude
12
+
13
+ # Model Configuration
14
+ # Claude models: claude-sonnet-4-5-20250929, claude-opus-4-6-20250929, claude-haiku-4-5-20251001
15
+ # Gemini models: gemini-2.0-flash, gemini-1.5-pro
16
+ # Ollama models: llama3.2, mistral, etc. (requires local Ollama server)
17
+ model: claude-sonnet-4-5-20250929
18
+
19
+ # Example configurations for other providers:
20
+ #
21
+ # --- Claude (Anthropic) ---
22
+ # provider: claude
23
+ # model: claude-sonnet-4-5-20250929
24
+ # Requires: ANTHROPIC_API_KEY environment variable
25
+ #
26
+ # --- Gemini (Google) ---
27
+ # provider: gemini
28
+ # model: gemini-2.0-flash
29
+ # Requires: GOOGLE_API_KEY environment variable
30
+ #
31
+ # --- Ollama (Local) ---
32
+ # provider: ollama
33
+ # model: llama3.2
34
+ # Requires: Ollama server running locally (no API key needed)
35
+ # Install: https://ollama.ai
36
+
37
+ # Optional: Custom template directory
38
+ # templates: ./templates
39
+
40
+ # Optional: Default output directory
41
+ # outputDir: ./output
42
+
43
+ # Optional: Logging configuration
44
+ # log:
45
+ # enabled: true
46
+ # path: ./yuuhitsu.log
47
+ `;
48
+ export const initCommand = new Command("init")
49
+ .description("Initialize a yuuhitsu config file")
50
+ .option("--force", "Overwrite existing config file")
51
+ .action(async (opts) => {
52
+ const configPath = join(process.cwd(), "yuuhitsu.config.yaml");
53
+ // Check if config already exists
54
+ if (existsSync(configPath) && !opts.force) {
55
+ process.stderr.write(chalk.red("Error:") + " Config file already exists: " + configPath + "\n" +
56
+ chalk.yellow("Hint:") + " Use --force to overwrite the existing file\n");
57
+ process.exit(1);
58
+ }
59
+ // Write config file
60
+ try {
61
+ writeFileSync(configPath, DEFAULT_CONFIG_TEMPLATE, "utf-8");
62
+ if (opts.force && existsSync(configPath)) {
63
+ process.stdout.write(chalk.green("✓") + " Config file overwritten: " + configPath + "\n");
64
+ }
65
+ else {
66
+ process.stdout.write(chalk.green("✓") + " Config file created: " + configPath + "\n");
67
+ }
68
+ process.stdout.write("\n" +
69
+ "Next steps:\n" +
70
+ "1. Set your API key:\n" +
71
+ " - For Claude: export ANTHROPIC_API_KEY='your-key'\n" +
72
+ " - For Gemini: export GOOGLE_API_KEY='your-key'\n" +
73
+ " - For Ollama: Start Ollama server (ollama serve)\n" +
74
+ "2. Run a command: yuuhitsu translate --input file.md --lang ja\n");
75
+ }
76
+ catch (err) {
77
+ process.stderr.write(chalk.red("Error:") + " Failed to create config file\n" +
78
+ chalk.yellow("Hint:") + " " + (err instanceof Error ? err.message : String(err)) + "\n");
79
+ process.exit(1);
80
+ }
81
+ });
82
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0C/B,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,SAAS,EAAE,gCAAgC,CAAC;KACnD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,sBAAsB,CAAC,CAAC;IAE/D,iCAAiC;IACjC,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,+BAA+B,GAAG,UAAU,GAAG,IAAI;YACzE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,+CAA+C,CACxE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC;QACH,aAAa,CAAC,UAAU,EAAE,uBAAuB,EAAE,OAAO,CAAC,CAAC;QAE5D,IAAI,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,4BAA4B,GAAG,UAAU,GAAG,IAAI,CACpE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,wBAAwB,GAAG,UAAU,GAAG,IAAI,CAChE,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI;YACJ,eAAe;YACf,wBAAwB;YACxB,wDAAwD;YACxD,qDAAqD;YACrD,uDAAuD;YACvD,kEAAkE,CACnE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,iCAAiC;YACvD,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CACxF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/translate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,gBAAgB,SA8DzB,CAAC"}
1
+ {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/translate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,gBAAgB,SA4FzB,CAAC"}
@@ -4,49 +4,76 @@ import chalk from "chalk";
4
4
  import { loadConfig } from "../../config.js";
5
5
  import { createProvider } from "../../provider/index.js";
6
6
  import { translateFile } from "../../tasks/translate.js";
7
+ import { batchTranslate, isGlobPattern } from "../../tasks/batch-translate.js";
7
8
  import { formatError, AppError } from "../../errors.js";
8
9
  export const translateCommand = new Command("translate")
9
10
  .description("Translate a Markdown document to another language")
10
- .requiredOption("--input <file>", "Input Markdown file")
11
+ .requiredOption("--input <file>", "Input Markdown file or glob pattern")
11
12
  .requiredOption("--lang <code>", "Target language code (e.g., ja, en, zh, ko)")
12
13
  .option("--output <file>", "Output file path (default: <input>.<lang>.md)")
14
+ .option("--output-dir <dir>", "Output directory for batch translation (preserves directory structure)")
13
15
  .action(async (opts, cmd) => {
14
16
  const globalOpts = cmd.parent?.opts() ?? {};
15
17
  const configPath = globalOpts.config ?? "./yuuhitsu.config.yaml";
16
18
  const dryRun = globalOpts.dryRun ?? false;
17
19
  const verbose = globalOpts.verbose ?? false;
18
20
  try {
19
- // Validate input file exists
20
- if (!existsSync(opts.input)) {
21
- throw new AppError(`Input file not found: ${opts.input}`, "Check the file path and try again.");
22
- }
23
21
  // Load config
24
22
  const config = await loadConfig(configPath);
25
23
  if (verbose) {
26
24
  process.stderr.write(`${chalk.gray(`Provider: ${config.provider}, Model: ${config.model}`)}\n`);
27
25
  }
28
- // Dry-run mode
29
- if (dryRun) {
30
- const outputPath = opts.output || `${opts.input.replace(/\.md$/, "")}.${opts.lang}.md`;
31
- process.stdout.write(`${chalk.cyan("[dry-run]")} Would translate:\n` +
32
- ` Input: ${opts.input}\n` +
33
- ` Output: ${outputPath}\n` +
34
- ` Language: ${opts.lang}\n` +
35
- ` Provider: ${config.provider}\n` +
36
- ` Model: ${config.model}\n`);
37
- return;
26
+ // Check if input is a glob pattern
27
+ if (isGlobPattern(opts.input)) {
28
+ // Batch translation mode
29
+ const provider = dryRun ? undefined : createProvider(config.provider, config.model);
30
+ if (dryRun) {
31
+ process.stdout.write(`${chalk.cyan("[dry-run]")} Batch translate mode:\n` +
32
+ ` Pattern: ${opts.input}\n` +
33
+ ` Language: ${opts.lang}\n` +
34
+ ` Provider: ${config.provider}\n` +
35
+ ` Model: ${config.model}\n` +
36
+ (opts.outputDir ? ` Output dir: ${opts.outputDir}\n` : "") +
37
+ `\n`);
38
+ }
39
+ await batchTranslate({
40
+ pattern: opts.input,
41
+ targetLang: opts.lang,
42
+ provider,
43
+ outputDir: opts.outputDir,
44
+ dryRun,
45
+ verbose,
46
+ });
47
+ }
48
+ else {
49
+ // Single file translation mode (original behavior)
50
+ // Validate input file exists
51
+ if (!existsSync(opts.input)) {
52
+ throw new AppError(`Input file not found: ${opts.input}`, "Check the file path and try again.");
53
+ }
54
+ // Dry-run mode
55
+ if (dryRun) {
56
+ const outputPath = opts.output || `${opts.input.replace(/\.md$/, "")}.${opts.lang}.md`;
57
+ process.stdout.write(`${chalk.cyan("[dry-run]")} Would translate:\n` +
58
+ ` Input: ${opts.input}\n` +
59
+ ` Output: ${outputPath}\n` +
60
+ ` Language: ${opts.lang}\n` +
61
+ ` Provider: ${config.provider}\n` +
62
+ ` Model: ${config.model}\n`);
63
+ return;
64
+ }
65
+ // Create provider
66
+ const provider = createProvider(config.provider, config.model);
67
+ // Execute translation
68
+ const result = await translateFile({
69
+ provider,
70
+ inputPath: opts.input,
71
+ outputPath: opts.output,
72
+ targetLang: opts.lang,
73
+ });
74
+ process.stdout.write(`${chalk.green("✓")} Translated to ${result.outputPath}\n` +
75
+ ` Tokens: ${result.usage.totalTokens} (${result.chunks} chunk${result.chunks > 1 ? "s" : ""})\n`);
38
76
  }
39
- // Create provider
40
- const provider = createProvider(config.provider, config.model);
41
- // Execute translation
42
- const result = await translateFile({
43
- provider,
44
- inputPath: opts.input,
45
- outputPath: opts.output,
46
- targetLang: opts.lang,
47
- });
48
- process.stdout.write(`${chalk.green("✓")} Translated to ${result.outputPath}\n` +
49
- ` Tokens: ${result.usage.totalTokens} (${result.chunks} chunk${result.chunks > 1 ? "s" : ""})\n`);
50
77
  }
51
78
  catch (err) {
52
79
  process.stderr.write(formatError(err) + "\n");
@@ -1 +1 @@
1
- {"version":3,"file":"translate.js","sourceRoot":"","sources":["../../../src/cli/commands/translate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../../../src/cli/commands/translate.ts"],"names":[],"mappings":"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"}
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAoB9B,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAsB9B,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/cli/index.js CHANGED
@@ -5,6 +5,8 @@ import { join, dirname } from "path";
5
5
  import { fileURLToPath } from "url";
6
6
  import { formatError } from "../errors.js";
7
7
  import { translateCommand } from "./commands/translate.js";
8
+ import { initCommand } from "./commands/init.js";
9
+ import { glossaryCommand } from "./commands/glossary.js";
8
10
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
11
  function getVersion() {
10
12
  try {
@@ -24,7 +26,9 @@ program
24
26
  .option("--dry-run", "Show what would be done without making API calls")
25
27
  .option("--verbose", "Enable verbose output");
26
28
  // Register commands
29
+ program.addCommand(initCommand);
27
30
  program.addCommand(translateCommand);
31
+ program.addCommand(glossaryCommand);
28
32
  program.parseAsync(process.argv).catch((err) => {
29
33
  process.stderr.write(formatError(err) + "\n");
30
34
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,OAAO,CAAC,CAC7D,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CACV,oDAAoD,CACrD;KACA,OAAO,CAAC,UAAU,EAAE,CAAC;KACrB,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,wBAAwB,CAAC;KACvE,MAAM,CAAC,WAAW,EAAE,kDAAkD,CAAC;KACvE,MAAM,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAEhD,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAErC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,OAAO,CAAC,CAC7D,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CACV,oDAAoD,CACrD;KACA,OAAO,CAAC,UAAU,EAAE,CAAC;KACrB,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,wBAAwB,CAAC;KACvE,MAAM,CAAC,WAAW,EAAE,kDAAkD,CAAC;KACvE,MAAM,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAEhD,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AAEpC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/config.d.ts CHANGED
@@ -5,6 +5,7 @@ export interface AppConfig {
5
5
  model: string;
6
6
  templates?: string;
7
7
  outputDir?: string;
8
+ glossary?: string;
8
9
  log?: {
9
10
  enabled?: boolean;
10
11
  path?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,mBAAmB,yCAA0C,CAAC;AACpE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAAC,CAmDpB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,mBAAmB,yCAA0C,CAAC;AACpE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAAC,CAyDpB"}
package/dist/config.js CHANGED
@@ -41,6 +41,12 @@ export async function loadConfig(configPath, envDir) {
41
41
  config.templates = raw.templates;
42
42
  if (raw.outputDir)
43
43
  config.outputDir = raw.outputDir;
44
+ if (raw.glossary !== undefined) {
45
+ if (typeof raw.glossary !== "string") {
46
+ throw new Error('Config field "glossary" must be a string path');
47
+ }
48
+ config.glossary = raw.glossary;
49
+ }
44
50
  if (raw.log) {
45
51
  config.log = {
46
52
  enabled: raw.log.enabled ?? false,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAcpE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,MAAe;IAEf,0DAA0D;IAC1D,IAAI,MAAM,EAAE,CAAC;QACX,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,YAAY,EAAE,CAAC,CAAC,4BAA4B;IAC9C,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAE3B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,2BAA2B,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,MAAM,GAAc;QACxB,QAAQ;QACR,KAAK;KACN,CAAC;IAEF,IAAI,GAAG,CAAC,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IACpD,IAAI,GAAG,CAAC,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IACpD,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,GAAG;YACX,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK;YACjC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI;SACnB,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAepE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,MAAe;IAEf,0DAA0D;IAC1D,IAAI,MAAM,EAAE,CAAC;QACX,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,YAAY,EAAE,CAAC,CAAC,4BAA4B;IAC9C,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAE3B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,2BAA2B,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,MAAM,GAAc;QACxB,QAAQ;QACR,KAAK;KACN,CAAC;IAEF,IAAI,GAAG,CAAC,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IACpD,IAAI,GAAG,CAAC,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IACpD,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IACjC,CAAC;IACD,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,GAAG;YACX,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK;YACjC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI;SACnB,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/errors.d.ts CHANGED
File without changes
File without changes
package/dist/errors.js CHANGED
File without changes
File without changes
package/dist/logger.d.ts CHANGED
File without changes
File without changes
package/dist/logger.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes