@vertana/cli 0.1.0-dev.1 → 0.1.0-dev.10
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.
- package/README.md +93 -0
- package/dist/index.cjs +24 -1
- package/dist/index.mjs +24 -1
- package/package.json +2 -1
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
@vertana/cli
|
|
2
|
+
============
|
|
3
|
+
|
|
4
|
+
[![JSR][JSR badge]][JSR]
|
|
5
|
+
[![npm][npm badge]][npm]
|
|
6
|
+
|
|
7
|
+
> [!CAUTION]
|
|
8
|
+
> Vertana is currently in early development for proof of concept purposes,
|
|
9
|
+
> and is not yet ready for production use. The API is subject to change,
|
|
10
|
+
> and there may be bugs or missing features.
|
|
11
|
+
|
|
12
|
+
Command-line interface for [Vertana] translation. Translate documents from
|
|
13
|
+
the terminal with support for multiple providers (OpenAI, Anthropic, Google).
|
|
14
|
+
|
|
15
|
+
[JSR]: https://jsr.io/@vertana/cli
|
|
16
|
+
[JSR badge]: https://jsr.io/badges/@vertana/cli
|
|
17
|
+
[npm]: https://www.npmjs.com/package/@vertana/cli
|
|
18
|
+
[npm badge]: https://img.shields.io/npm/v/@vertana/cli?logo=npm
|
|
19
|
+
[Vertana]: https://vertana.org/
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Installation
|
|
23
|
+
------------
|
|
24
|
+
|
|
25
|
+
~~~~ bash
|
|
26
|
+
deno install -g --name vertana --allow-all jsr:@vertana/cli
|
|
27
|
+
npm install -g @vertana/cli
|
|
28
|
+
pnpm add -g @vertana/cli
|
|
29
|
+
bun add -g @vertana/cli
|
|
30
|
+
~~~~
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Quick start
|
|
34
|
+
-----------
|
|
35
|
+
|
|
36
|
+
First, configure your API key and default model:
|
|
37
|
+
|
|
38
|
+
~~~~ bash
|
|
39
|
+
vertana config api-key openai
|
|
40
|
+
vertana config model openai:gpt-4o
|
|
41
|
+
~~~~
|
|
42
|
+
|
|
43
|
+
Then translate a file:
|
|
44
|
+
|
|
45
|
+
~~~~ bash
|
|
46
|
+
vertana translate -t ko document.md
|
|
47
|
+
~~~~
|
|
48
|
+
|
|
49
|
+
Or pipe text through stdin:
|
|
50
|
+
|
|
51
|
+
~~~~ bash
|
|
52
|
+
echo "Hello, world!" | vertana translate -t ko
|
|
53
|
+
~~~~
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Commands
|
|
57
|
+
--------
|
|
58
|
+
|
|
59
|
+
### translate
|
|
60
|
+
|
|
61
|
+
Translate text or files to a target language.
|
|
62
|
+
|
|
63
|
+
~~~~ bash
|
|
64
|
+
vertana translate [options] [input]
|
|
65
|
+
~~~~
|
|
66
|
+
|
|
67
|
+
Options:
|
|
68
|
+
|
|
69
|
+
- `-t, --target LANG`: Target language (required)
|
|
70
|
+
- `-s, --source LANG`: Source language (optional, auto-detected)
|
|
71
|
+
- `-T, --type TYPE`: Media type (`text/plain`, `text/markdown`, `text/html`)
|
|
72
|
+
- `--tone TONE`: Translation tone (formal, informal, technical, etc.)
|
|
73
|
+
- `--domain DOMAIN`: Subject domain for terminology
|
|
74
|
+
- `-g, --glossary TERM=TRANS`: Add glossary entry (repeatable)
|
|
75
|
+
- `--glossary-file FILE`: Load glossary from file
|
|
76
|
+
- `-o, --output FILE`: Output file (defaults to stdout)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### config
|
|
80
|
+
|
|
81
|
+
Manage configuration settings.
|
|
82
|
+
|
|
83
|
+
~~~~ bash
|
|
84
|
+
vertana config model [PROVIDER:MODEL] # Set or display default model
|
|
85
|
+
vertana config api-key PROVIDER [KEY] # Manage API keys
|
|
86
|
+
~~~~
|
|
87
|
+
|
|
88
|
+
Supported providers: `openai`, `anthropic`, `google`
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
For more resources, see the [docs].
|
|
92
|
+
|
|
93
|
+
[docs]: https://vertana.org/
|
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ let node_fs = require("node:fs");
|
|
|
41
41
|
let _napi_rs_keyring = require("@napi-rs/keyring");
|
|
42
42
|
let node_os = require("node:os");
|
|
43
43
|
let node_path = require("node:path");
|
|
44
|
+
let _vertana_context_web = require("@vertana/context-web");
|
|
44
45
|
let _vertana_facade = require("@vertana/facade");
|
|
45
46
|
let node_stream = require("node:stream");
|
|
46
47
|
|
|
@@ -421,6 +422,7 @@ const translateCommand = (0, _optique_core_primitives.command)("translate", (0,
|
|
|
421
422
|
mustExist: true,
|
|
422
423
|
type: "file"
|
|
423
424
|
}))),
|
|
425
|
+
fetchLinks: (0, _optique_core_primitives.option)("-L", "--fetch-links", { description: _optique_core_message.message`Fetch linked pages for additional context.` }),
|
|
424
426
|
output: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("-o", "--output", (0, _optique_run_valueparser.path)({ metavar: "FILE" }))),
|
|
425
427
|
input: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.argument)((0, _optique_run_valueparser.path)({ metavar: "FILE" })))
|
|
426
428
|
}));
|
|
@@ -577,12 +579,14 @@ async function executeTranslate(result) {
|
|
|
577
579
|
return;
|
|
578
580
|
}
|
|
579
581
|
const glossary = buildGlossary(result.glossary, result.glossaryFile);
|
|
582
|
+
const contextSources = buildContextSources(inputText, result.mediaType, result.fetchLinks);
|
|
580
583
|
const translation = await (0, _vertana_facade.translate)(model, result.target, inputText, {
|
|
581
584
|
sourceLanguage: result.source,
|
|
582
585
|
mediaType: result.mediaType,
|
|
583
586
|
tone: result.tone,
|
|
584
587
|
domain: result.domain,
|
|
585
|
-
glossary: glossary.length > 0 ? glossary : void 0
|
|
588
|
+
glossary: glossary.length > 0 ? glossary : void 0,
|
|
589
|
+
contextSources: contextSources.length > 0 ? contextSources : void 0
|
|
586
590
|
});
|
|
587
591
|
if (result.output != null) try {
|
|
588
592
|
(0, node_fs.writeFileSync)(result.output, translation.text + "\n", "utf-8");
|
|
@@ -612,6 +616,25 @@ function buildGlossary(cliEntries, filePath) {
|
|
|
612
616
|
if (cliEntries.length > 0) glossaries.push(cliEntries);
|
|
613
617
|
return mergeGlossaries(...glossaries);
|
|
614
618
|
}
|
|
619
|
+
/**
|
|
620
|
+
* Builds context sources based on CLI options.
|
|
621
|
+
*
|
|
622
|
+
* @param text The input text.
|
|
623
|
+
* @param mediaType The media type of the text.
|
|
624
|
+
* @param fetchLinksEnabled Whether to fetch linked pages.
|
|
625
|
+
* @returns Array of context sources.
|
|
626
|
+
*/
|
|
627
|
+
function buildContextSources(text$5, mediaType, fetchLinksEnabled) {
|
|
628
|
+
const sources = [];
|
|
629
|
+
if (fetchLinksEnabled) {
|
|
630
|
+
sources.push((0, _vertana_context_web.fetchLinkedPages)({
|
|
631
|
+
text: text$5,
|
|
632
|
+
mediaType
|
|
633
|
+
}));
|
|
634
|
+
sources.push(_vertana_context_web.fetchWebPage);
|
|
635
|
+
}
|
|
636
|
+
return sources;
|
|
637
|
+
}
|
|
615
638
|
|
|
616
639
|
//#endregion
|
|
617
640
|
//#region src/index.ts
|
package/dist/index.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
13
13
|
import { Entry } from "@napi-rs/keyring";
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
15
|
import { join } from "node:path";
|
|
16
|
+
import { fetchLinkedPages, fetchWebPage } from "@vertana/context-web";
|
|
16
17
|
import { translate } from "@vertana/facade";
|
|
17
18
|
import { Readable } from "node:stream";
|
|
18
19
|
|
|
@@ -393,6 +394,7 @@ const translateCommand = command("translate", object({
|
|
|
393
394
|
mustExist: true,
|
|
394
395
|
type: "file"
|
|
395
396
|
}))),
|
|
397
|
+
fetchLinks: option("-L", "--fetch-links", { description: message`Fetch linked pages for additional context.` }),
|
|
396
398
|
output: optional(option("-o", "--output", path({ metavar: "FILE" }))),
|
|
397
399
|
input: optional(argument(path({ metavar: "FILE" })))
|
|
398
400
|
}));
|
|
@@ -549,12 +551,14 @@ async function executeTranslate(result) {
|
|
|
549
551
|
return;
|
|
550
552
|
}
|
|
551
553
|
const glossary = buildGlossary(result.glossary, result.glossaryFile);
|
|
554
|
+
const contextSources = buildContextSources(inputText, result.mediaType, result.fetchLinks);
|
|
552
555
|
const translation = await translate(model, result.target, inputText, {
|
|
553
556
|
sourceLanguage: result.source,
|
|
554
557
|
mediaType: result.mediaType,
|
|
555
558
|
tone: result.tone,
|
|
556
559
|
domain: result.domain,
|
|
557
|
-
glossary: glossary.length > 0 ? glossary : void 0
|
|
560
|
+
glossary: glossary.length > 0 ? glossary : void 0,
|
|
561
|
+
contextSources: contextSources.length > 0 ? contextSources : void 0
|
|
558
562
|
});
|
|
559
563
|
if (result.output != null) try {
|
|
560
564
|
writeFileSync(result.output, translation.text + "\n", "utf-8");
|
|
@@ -584,6 +588,25 @@ function buildGlossary(cliEntries, filePath) {
|
|
|
584
588
|
if (cliEntries.length > 0) glossaries.push(cliEntries);
|
|
585
589
|
return mergeGlossaries(...glossaries);
|
|
586
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Builds context sources based on CLI options.
|
|
593
|
+
*
|
|
594
|
+
* @param text The input text.
|
|
595
|
+
* @param mediaType The media type of the text.
|
|
596
|
+
* @param fetchLinksEnabled Whether to fetch linked pages.
|
|
597
|
+
* @returns Array of context sources.
|
|
598
|
+
*/
|
|
599
|
+
function buildContextSources(text$1, mediaType, fetchLinksEnabled) {
|
|
600
|
+
const sources = [];
|
|
601
|
+
if (fetchLinksEnabled) {
|
|
602
|
+
sources.push(fetchLinkedPages({
|
|
603
|
+
text: text$1,
|
|
604
|
+
mediaType
|
|
605
|
+
}));
|
|
606
|
+
sources.push(fetchWebPage);
|
|
607
|
+
}
|
|
608
|
+
return sources;
|
|
609
|
+
}
|
|
587
610
|
|
|
588
611
|
//#endregion
|
|
589
612
|
//#region src/index.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertana/cli",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.10+fd710745",
|
|
4
4
|
"description": "Command-line interface for Vertana translation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"LLM",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"@optique/core": "^0.8.3",
|
|
63
63
|
"@optique/logtape": "^0.8.3",
|
|
64
64
|
"@optique/run": "^0.8.3",
|
|
65
|
+
"@vertana/context-web": "",
|
|
65
66
|
"@vertana/facade": ""
|
|
66
67
|
},
|
|
67
68
|
"peerDependencies": {
|