@vertana/cli 0.1.0-dev.8 → 0.2.0-dev.15

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/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
 
@@ -399,13 +400,13 @@ const globalOptions = (0, _optique_core_constructs.object)({ logging: (0, _optiq
399
400
  */
400
401
  const translateCommand = (0, _optique_core_primitives.command)("translate", (0, _optique_core_constructs.object)({
401
402
  command: (0, _optique_core_primitives.constant)("translate"),
402
- target: (0, _optique_core_primitives.option)("-t", "--target", (0, _optique_core_valueparser.string)({ metavar: "LANG" })),
403
- source: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("-s", "--source", (0, _optique_core_valueparser.string)({ metavar: "LANG" }))),
403
+ target: (0, _optique_core_primitives.option)("-t", "--target", (0, _optique_core_valueparser.string)({ metavar: "LANG" }), { description: _optique_core_message.message`Target language code (e.g., ${"ko"}, ${"ja"}, ${"es"}).` }),
404
+ source: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("-s", "--source", (0, _optique_core_valueparser.string)({ metavar: "LANG" }), { description: _optique_core_message.message`Source language code. Auto-detected if omitted.` })),
404
405
  mediaType: (0, _optique_core_modifiers.withDefault)((0, _optique_core_primitives.option)("-T", "--type", (0, _optique_core_valueparser.choice)([
405
406
  "text/plain",
406
407
  "text/markdown",
407
408
  "text/html"
408
- ])), "text/plain"),
409
+ ]), { description: _optique_core_message.message`Media type of the input text.` }), "text/plain"),
409
410
  tone: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("--tone", (0, _optique_core_valueparser.choice)([
410
411
  "formal",
411
412
  "informal",
@@ -414,23 +415,24 @@ const translateCommand = (0, _optique_core_primitives.command)("translate", (0,
414
415
  "professional",
415
416
  "literary",
416
417
  "journalistic"
417
- ]))),
418
- domain: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("--domain", (0, _optique_core_valueparser.string)())),
419
- glossary: (0, _optique_core_modifiers.multiple)((0, _optique_core_primitives.option)("-g", "--glossary", glossaryEntry())),
418
+ ]), { description: _optique_core_message.message`Tone of the translation.` })),
419
+ domain: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("--domain", (0, _optique_core_valueparser.string)(), { description: _optique_core_message.message`Domain or context (e.g., ${"legal"}, ${"medical"}, ${"tech"}).` })),
420
+ glossary: (0, _optique_core_modifiers.multiple)((0, _optique_core_primitives.option)("-g", "--glossary", glossaryEntry(), { description: _optique_core_message.message`Term translation mapping. Can be repeated.` })),
420
421
  glossaryFile: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("--glossary-file", (0, _optique_run_valueparser.path)({
421
422
  mustExist: true,
422
423
  type: "file"
423
- }))),
424
- output: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("-o", "--output", (0, _optique_run_valueparser.path)({ metavar: "FILE" }))),
425
- input: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.argument)((0, _optique_run_valueparser.path)({ metavar: "FILE" })))
426
- }));
424
+ }), { description: _optique_core_message.message`Path to a JSON file with glossary entries.` })),
425
+ fetchLinks: (0, _optique_core_primitives.option)("-L", "--fetch-links", { description: _optique_core_message.message`Fetch linked pages for additional context.` }),
426
+ output: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.option)("-o", "--output", (0, _optique_run_valueparser.path)({ metavar: "FILE" }), { description: _optique_core_message.message`Output file path. Writes to stdout if omitted.` })),
427
+ input: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.argument)((0, _optique_run_valueparser.path)({ metavar: "FILE" }), { description: _optique_core_message.message`Input file. Reads from stdin if omitted.` }))
428
+ }), { description: _optique_core_message.message`Translate text to another language using an LLM.` });
427
429
  /**
428
430
  * Parser for the "config model" subcommand.
429
431
  */
430
432
  const configModelCommand = (0, _optique_core_primitives.command)("model", (0, _optique_core_constructs.object)({
431
433
  subcommand: (0, _optique_core_primitives.constant)("model"),
432
- value: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.argument)(modelCode()))
433
- }));
434
+ value: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.argument)(modelCode(), { description: _optique_core_message.message`Model to configure in provider:model format.` }))
435
+ }), { description: _optique_core_message.message`Get or set the default LLM model.` });
434
436
  /**
435
437
  * Parser for the "config api-key" subcommand.
436
438
  */
@@ -440,16 +442,16 @@ const configApiKeyCommand = (0, _optique_core_primitives.command)("api-key", (0,
440
442
  "openai",
441
443
  "anthropic",
442
444
  "google"
443
- ], { metavar: "PROVIDER" })),
444
- key: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.argument)((0, _optique_core_valueparser.string)({ metavar: "KEY" })))
445
- }));
445
+ ], { metavar: "PROVIDER" }), { description: _optique_core_message.message`Provider name.` }),
446
+ key: (0, _optique_core_modifiers.optional)((0, _optique_core_primitives.argument)((0, _optique_core_valueparser.string)({ metavar: "KEY" }), { description: _optique_core_message.message`API key value. Prompts if omitted.` }))
447
+ }), { description: _optique_core_message.message`Get or set an API key for a provider.` });
446
448
  /**
447
449
  * Parser for the "config" subcommand with nested subcommands.
448
450
  */
449
451
  const configCommand = (0, _optique_core_primitives.command)("config", (0, _optique_core_constructs.object)({
450
452
  command: (0, _optique_core_primitives.constant)("config"),
451
453
  action: (0, _optique_core_constructs.or)(configModelCommand, configApiKeyCommand)
452
- }));
454
+ }), { description: _optique_core_message.message`Configure CLI settings such as model and API keys.` });
453
455
  /**
454
456
  * The main CLI parser combining all subcommands.
455
457
  */
@@ -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
 
@@ -371,13 +372,13 @@ const globalOptions = object({ logging: loggingOptions({ level: "verbosity" }) }
371
372
  */
372
373
  const translateCommand = command("translate", object({
373
374
  command: constant("translate"),
374
- target: option("-t", "--target", string({ metavar: "LANG" })),
375
- source: optional(option("-s", "--source", string({ metavar: "LANG" }))),
375
+ target: option("-t", "--target", string({ metavar: "LANG" }), { description: message`Target language code (e.g., ${"ko"}, ${"ja"}, ${"es"}).` }),
376
+ source: optional(option("-s", "--source", string({ metavar: "LANG" }), { description: message`Source language code. Auto-detected if omitted.` })),
376
377
  mediaType: withDefault(option("-T", "--type", choice([
377
378
  "text/plain",
378
379
  "text/markdown",
379
380
  "text/html"
380
- ])), "text/plain"),
381
+ ]), { description: message`Media type of the input text.` }), "text/plain"),
381
382
  tone: optional(option("--tone", choice([
382
383
  "formal",
383
384
  "informal",
@@ -386,23 +387,24 @@ const translateCommand = command("translate", object({
386
387
  "professional",
387
388
  "literary",
388
389
  "journalistic"
389
- ]))),
390
- domain: optional(option("--domain", string())),
391
- glossary: multiple(option("-g", "--glossary", glossaryEntry())),
390
+ ]), { description: message`Tone of the translation.` })),
391
+ domain: optional(option("--domain", string(), { description: message`Domain or context (e.g., ${"legal"}, ${"medical"}, ${"tech"}).` })),
392
+ glossary: multiple(option("-g", "--glossary", glossaryEntry(), { description: message`Term translation mapping. Can be repeated.` })),
392
393
  glossaryFile: optional(option("--glossary-file", path({
393
394
  mustExist: true,
394
395
  type: "file"
395
- }))),
396
- output: optional(option("-o", "--output", path({ metavar: "FILE" }))),
397
- input: optional(argument(path({ metavar: "FILE" })))
398
- }));
396
+ }), { description: message`Path to a JSON file with glossary entries.` })),
397
+ fetchLinks: option("-L", "--fetch-links", { description: message`Fetch linked pages for additional context.` }),
398
+ output: optional(option("-o", "--output", path({ metavar: "FILE" }), { description: message`Output file path. Writes to stdout if omitted.` })),
399
+ input: optional(argument(path({ metavar: "FILE" }), { description: message`Input file. Reads from stdin if omitted.` }))
400
+ }), { description: message`Translate text to another language using an LLM.` });
399
401
  /**
400
402
  * Parser for the "config model" subcommand.
401
403
  */
402
404
  const configModelCommand = command("model", object({
403
405
  subcommand: constant("model"),
404
- value: optional(argument(modelCode()))
405
- }));
406
+ value: optional(argument(modelCode(), { description: message`Model to configure in provider:model format.` }))
407
+ }), { description: message`Get or set the default LLM model.` });
406
408
  /**
407
409
  * Parser for the "config api-key" subcommand.
408
410
  */
@@ -412,16 +414,16 @@ const configApiKeyCommand = command("api-key", object({
412
414
  "openai",
413
415
  "anthropic",
414
416
  "google"
415
- ], { metavar: "PROVIDER" })),
416
- key: optional(argument(string({ metavar: "KEY" })))
417
- }));
417
+ ], { metavar: "PROVIDER" }), { description: message`Provider name.` }),
418
+ key: optional(argument(string({ metavar: "KEY" }), { description: message`API key value. Prompts if omitted.` }))
419
+ }), { description: message`Get or set an API key for a provider.` });
418
420
  /**
419
421
  * Parser for the "config" subcommand with nested subcommands.
420
422
  */
421
423
  const configCommand = command("config", object({
422
424
  command: constant("config"),
423
425
  action: or(configModelCommand, configApiKeyCommand)
424
- }));
426
+ }), { description: message`Configure CLI settings such as model and API keys.` });
425
427
  /**
426
428
  * The main CLI parser combining all subcommands.
427
429
  */
@@ -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.8+2c1883ec",
3
+ "version": "0.2.0-dev.15+f34ed253",
4
4
  "description": "Command-line interface for Vertana translation",
5
5
  "keywords": [
6
6
  "LLM",
@@ -59,9 +59,10 @@
59
59
  "dependencies": {
60
60
  "@logtape/logtape": "^1.3.5",
61
61
  "@napi-rs/keyring": "^1.2.0",
62
- "@optique/core": "^0.8.3",
63
- "@optique/logtape": "^0.8.3",
64
- "@optique/run": "^0.8.3",
62
+ "@optique/core": "^0.8.5",
63
+ "@optique/logtape": "^0.8.5",
64
+ "@optique/run": "^0.8.5",
65
+ "@vertana/context-web": "",
65
66
  "@vertana/facade": ""
66
67
  },
67
68
  "peerDependencies": {