@iola_adm/iola-cli 0.2.42 → 0.2.44

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iola_adm/iola-cli",
3
- "version": "0.2.42",
3
+ "version": "0.2.44",
4
4
  "description": "CLI и AI-агент городского округа Йошкар-Ола.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/adm-iola/iola-cli#readme",
package/src/cli.js CHANGED
@@ -3787,10 +3787,10 @@ async function ensureYandexGoGeocoderReady() {
3787
3787
  async function buildYandexGoDeeplinkFromOptions(options = {}) {
3788
3788
  const from = options.from || options._?.[0] || "";
3789
3789
  const to = options.to || options._?.[1] || "";
3790
- if (!from || !to) throw new Error('Укажите маршрут: iola yandex go link --from "Медведево, Школьная 15" --to "Медведево, Советская 20"');
3790
+ if (!from || !to) throw new Error('Укажите маршрут: iola yandex go link --from "Йошкар-Ола, Красноармейская 43" --to "Йошкар-Ола, Гагарина 8"');
3791
3791
  const ambiguous = [from, to].find((point) => isAmbiguousPersonalYandexGoPoint(point));
3792
3792
  if (ambiguous) {
3793
- throw new Error(`Не знаю адрес "${ambiguous}". Укажите полный адрес отправления или сохраните его в настройках позже. Пример: "такси от Йошкар-Ола, улица ..., дом ... до Администрации Йошкар-Олы".`);
3793
+ throw new Error(`Не знаю адрес "${ambiguous}". Укажите полный адрес отправления или сохраните его в настройках позже. Пример: "такси от Йошкар-Ола, Красноармейская 43 до Администрации Йошкар-Олы".`);
3794
3794
  }
3795
3795
  const fromPoint = await resolveYandexGoPoint(from);
3796
3796
  const toPoint = await resolveYandexGoPoint(to);
@@ -3934,7 +3934,8 @@ function extractYandexGoRouteFromText(text, previousText = "") {
3934
3934
  .replace(/\s+/g, " ")
3935
3935
  .trim();
3936
3936
  const match = cleaned.match(/(?:от|из|с)\s+(.+?)\s+(?:до|в|на)\s+(.+)$/iu)
3937
- || cleaned.match(/^(.+?)\s*,?\s+(?:до|в)\s+(.+)$/iu);
3937
+ || cleaned.match(/^(.+?)\s*,?\s+(?:до|в)\s+(.+)$/iu)
3938
+ || splitYandexGoCommaRoute(cleaned);
3938
3939
  if (!match) {
3939
3940
  const partialFrom = cleaned.match(/(?:^|\s)(?:от|из|с)\s+(.+)$/iu)?.[1]?.trim() || "";
3940
3941
  const previousRoute = previousText ? extractYandexGoRouteFromText(previousText, "") : { from: "", to: "" };
@@ -3952,6 +3953,24 @@ function extractYandexGoRouteFromText(text, previousText = "") {
3952
3953
  return { from, to, tariff: tariffMatch ? normalizeYandexGoTariff(tariffMatch[1]) : "econom" };
3953
3954
  }
3954
3955
 
3956
+ function splitYandexGoCommaRoute(text) {
3957
+ const source = String(text || "").trim();
3958
+ const marker = source.match(/,\s*((?:администрац|мэри|йошкар|медведево|сем[её]новк)[\s\S]+)$/iu);
3959
+ if (marker?.index && marker.index > 3) {
3960
+ return [source, source.slice(0, marker.index).trim(), marker[1].trim()];
3961
+ }
3962
+ const parts = source.split(/\s*,\s*/u).filter(Boolean);
3963
+ if (parts.length === 2) return [source, parts[0], parts[1]];
3964
+ return null;
3965
+ }
3966
+
3967
+ function looksLikeYandexGoAddressPair(text) {
3968
+ const source = String(text || "").trim();
3969
+ if (!source.includes(",")) return false;
3970
+ if (!/(йошкар|медведево|сем[её]новк|администрац|мэри|ул\.|улица|проспект|пр-т|бульвар|переулок|\d)/iu.test(source)) return false;
3971
+ return Boolean(splitYandexGoCommaRoute(source));
3972
+ }
3973
+
3955
3974
  async function handleYandexMailWatch(args = []) {
3956
3975
  const [action = "status", ...rest] = args;
3957
3976
  const options = parseOptions(rest);
@@ -12568,7 +12587,7 @@ async function buildYandexDirectAnswer(question, history = []) {
12568
12587
  const mailContext = /Яндекс Почта|Письмо #|\bUID\b|#\d{3,}/iu.test(previousAssistantText);
12569
12588
  const mailFollowup = mailContext && isYandexMailFollowupQuestion(normalized, question);
12570
12589
  const goContext = /(?:Ссылка Яндекс Go|Для ссылки Яндекс Go|Не знаю адрес|Геокодер вернул|Укажите полный адрес отправления)/iu.test(previousAssistantText);
12571
- const goFollowup = goContext && /(?:^|\s)(?:от|из|с|до|в)\s+/iu.test(normalized);
12590
+ const goFollowup = goContext && (/(?:^|\s)(?:от|из|с|до|в)\s+/iu.test(normalized) || looksLikeYandexGoAddressPair(question));
12572
12591
  if (!isYandexServiceQuestion(normalized) && !mailFollowup && !goFollowup) return "";
12573
12592
  try {
12574
12593
  if (mailFollowup && (isYandexMailReadRequest(normalized) || isYandexMailSelectionQuestion(question))) {
@@ -12594,7 +12613,7 @@ async function buildYandexDirectAnswer(question, history = []) {
12594
12613
  && /(маршрут|ссылк|откуда|куда|поездк|такси|от\s+.+\s+до\s+)/iu.test(normalized))) {
12595
12614
  const route = extractYandexGoRouteFromText(question, previousUserText);
12596
12615
  if (!route.from || !route.to) {
12597
- return 'Для ссылки Яндекс Go нужны два адреса. Пример: "такси от Медведево, Школьная 15 до Медведево, Советская 20".';
12616
+ return 'Для ссылки Яндекс Go нужны два адреса. Пример: "такси от Йошкар-Ола, Красноармейская 43 до Йошкар-Ола, Гагарина 8".';
12598
12617
  }
12599
12618
  await ensureYandexGoGeocoderReady();
12600
12619
  const result = await buildYandexGoDeeplinkFromOptions({ from: route.from, to: route.to, tariff: route.tariff });
@@ -16715,8 +16734,12 @@ async function chooseOnboardComponents(status = null) {
16715
16734
  console.log("");
16716
16735
  console.log("Выберите компоненты через запятую:");
16717
16736
  console.log("0. выход в CLI [без настройки] - пропустить мастер");
16718
- for (const item of onboardComponentRows(componentStatus)) {
16719
- console.log(`${item.number}. ${item.title} [${item.status}] - ${item.hint}`);
16737
+ for (const group of onboardComponentGroups(componentStatus)) {
16738
+ console.log("");
16739
+ console.log(group.title);
16740
+ for (const item of group.rows) {
16741
+ console.log(`${item.number}. ${item.title} [${item.status}] - ${item.hint}`);
16742
+ }
16720
16743
  }
16721
16744
  console.log("");
16722
16745
  const rl = readline.createInterface({ input, output });
@@ -16728,19 +16751,18 @@ async function chooseOnboardComponents(status = null) {
16728
16751
  const map = {
16729
16752
  1: "workspace",
16730
16753
  2: "policy",
16731
- 3: "iola",
16732
- 4: "gigachat",
16733
- 5: "openai",
16734
- 6: "openrouter",
16735
- 7: "codex",
16736
- 8: "codex-mcp",
16737
- 9: "archive",
16738
- 10: "index",
16739
- 11: "browser",
16740
- 12: "ollama",
16741
- 13: "yandex",
16742
- 14: "yandex-cloud",
16743
- 15: "yandex-cloud",
16754
+ 3: "archive",
16755
+ 4: "index",
16756
+ 5: "browser",
16757
+ 6: "iola",
16758
+ 7: "ollama",
16759
+ 8: "gigachat",
16760
+ 9: "yandex",
16761
+ 10: "yandex-cloud",
16762
+ 11: "openai",
16763
+ 12: "openrouter",
16764
+ 13: "codex",
16765
+ 14: "codex-mcp",
16744
16766
  };
16745
16767
  return [...selected].map((item) => map[item] || item).filter(Boolean);
16746
16768
  } finally {
@@ -16783,37 +16805,69 @@ async function getOnboardComponentStatus() {
16783
16805
  };
16784
16806
  }
16785
16807
 
16786
- function onboardComponentRows(status) {
16787
- const rows = [
16788
- ["1", "workspace", "workspace и контекст", "рабочая папка, IOLA.md и .iola/context.md"],
16789
- ["2", "policy", "policy analyst", "разрешения и профиль аналитика"],
16790
- ["3", "iola", "IOLA локальная модель", "локальная модель найдена"],
16791
- ["4", "gigachat", "GigaChat API", "authorization key сохранен или есть в env"],
16792
- ["5", "openai", "OpenAI API", "API-ключ сохранен или есть в env"],
16793
- ["6", "openrouter", "OpenRouter API", "API-ключ сохранен или есть в env"],
16794
- ["7", "codex", "Codex CLI", "CLI установлен и авторизация найдена"],
16795
- ["8", "codex-mcp", "MCP для Codex", "можно переустановить/обновить"],
16796
- ["9", "archive", "7-Zip / архивы", "архиватор найден"],
16797
- ["10", "index", "Индекс локальных документов", "настраивается под выбранную папку"],
16798
- ["11", "browser", "Browser runtime", "Playwright/Chromium установлен"],
16799
- ["12", "ollama", "Ollama", "опциональный локальный runtime"],
16800
- ["13", "yandex", "Yandex Connector", "единый вход и категории сервисов Яндекса"],
16801
- ["14", "yandex-cloud", "Yandex Cloud Connector", "геокодинг и YandexGPT"],
16808
+ function onboardComponentGroups(status) {
16809
+ const groups = [
16810
+ {
16811
+ title: "Базовая настройка",
16812
+ rows: [
16813
+ ["1", "workspace", "Рабочая папка и контекст", "IOLA.md и .iola/context.md"],
16814
+ ["2", "policy", "Разрешения и безопасный режим", "профиль аналитика"],
16815
+ ["3", "archive", "7-Zip / архивы", "архиватор найден"],
16816
+ ["4", "index", "Индекс локальных документов", "выбранная папка"],
16817
+ ["5", "browser", "Браузерный модуль", "Playwright/Chromium"],
16818
+ ],
16819
+ },
16820
+ {
16821
+ title: "Локальный AI",
16822
+ rows: [
16823
+ ["6", "iola", "IOLA локальная модель", "локальная модель найдена"],
16824
+ ["7", "ollama", "Ollama", "опциональный локальный runtime"],
16825
+ ],
16826
+ },
16827
+ {
16828
+ title: "Российские AI и сервисы",
16829
+ rows: [
16830
+ ["8", "gigachat", "GigaChat API", "authorization key сохранен или есть в env"],
16831
+ ["9", "yandex", "Yandex Connector", "Диск, Почта, Календарь, Контакты"],
16832
+ ["10", "yandex-cloud", "Yandex Cloud Connector", "геокодинг и YandexGPT"],
16833
+ ],
16834
+ },
16835
+ {
16836
+ title: "Зарубежные AI",
16837
+ rows: [
16838
+ ["11", "openai", "OpenAI API", "API-ключ сохранен или есть в env"],
16839
+ ["12", "openrouter", "OpenRouter API", "API-ключ сохранен или есть в env"],
16840
+ ],
16841
+ },
16842
+ {
16843
+ title: "Codex",
16844
+ rows: [
16845
+ ["13", "codex", "Codex CLI", "CLI установлен и авторизация найдена"],
16846
+ ["14", "codex-mcp", "Подключение IOLA к Codex", "MCP для Codex"],
16847
+ ],
16848
+ },
16802
16849
  ];
16803
- return rows.map(([number, key, title, hint]) => ({ number, key, title, hint, status: status[key] ? "готово" : "не настроено" }));
16850
+ return groups.map((group) => ({
16851
+ ...group,
16852
+ rows: group.rows.map(([number, key, title, hint]) => ({ number, key, title, hint, status: status[key] ? "готово" : "не настроено" })),
16853
+ }));
16854
+ }
16855
+
16856
+ function onboardComponentRows(status) {
16857
+ return onboardComponentGroups(status).flatMap((group) => group.rows);
16804
16858
  }
16805
16859
 
16806
16860
  function defaultOnboardSelection(status) {
16807
16861
  const defaults = [];
16808
16862
  if (!status.workspace) defaults.push("1");
16809
16863
  if (!status.policy) defaults.push("2");
16810
- if (!status.iola) defaults.push("3");
16811
- if (!status.archive) defaults.push("9");
16864
+ if (!status.archive) defaults.push("3");
16865
+ if (!status.iola) defaults.push("6");
16812
16866
  return defaults.length ? defaults : ["1", "2"];
16813
16867
  }
16814
16868
 
16815
16869
  function defaultOnboardComponents(status) {
16816
- const map = { 1: "workspace", 2: "policy", 3: "iola", 4: "gigachat", 5: "openai", 6: "openrouter", 7: "codex", 8: "codex-mcp", 9: "archive", 10: "index", 11: "browser", 12: "ollama", 13: "yandex", 14: "yandex-cloud", 15: "yandex-cloud" };
16870
+ const map = { 1: "workspace", 2: "policy", 3: "archive", 4: "index", 5: "browser", 6: "iola", 7: "ollama", 8: "gigachat", 9: "yandex", 10: "yandex-cloud", 11: "openai", 12: "openrouter", 13: "codex", 14: "codex-mcp" };
16817
16871
  return defaultOnboardSelection(status).map((item) => map[item]).filter(Boolean);
16818
16872
  }
16819
16873
 
@@ -18,7 +18,7 @@ iola master
18
18
  В мастере выберите:
19
19
 
20
20
  ```text
21
- 14. Yandex Cloud Connector - геокодинг и YandexGPT
21
+ 10. Yandex Cloud Connector - геокодинг и YandexGPT
22
22
  ```
23
23
 
24
24
  CLI не просто открывает консоль. Он печатает короткую инструкцию, что делать дальше, и только потом просит вставить ключи.
@@ -90,8 +90,8 @@ iola geo route-context "школа 7"
90
90
  Геокодер также нужен для Яндекс Go deeplink:
91
91
 
92
92
  ```bash
93
- iola yandex go link --from "Медведево, Школьная 15" --to "Медведево, Советская 20"
94
- iola yandex go open --from "Медведево, Школьная 15" --to "Медведево, Советская 20" --tariff econom
93
+ iola yandex go link --from "Йошкар-Ола, Красноармейская 43" --to "Йошкар-Ола, Гагарина 8"
94
+ iola yandex go open --from "Йошкар-Ола, Красноармейская 43" --to "Йошкар-Ола, Гагарина 8" --tariff econom
95
95
  ```
96
96
 
97
97
  Если ключ геокодера не найден, CLI пишет понятную ошибку и предлагает:
@@ -121,7 +121,7 @@ CLI не нажимает кнопку заказа, не подтверждае
121
121
 
122
122
  ```bash
123
123
  iola yandex go link --from "Йошкар-Ола, Ленинский 24" --to "Йошкар-Ола, Кремлевская 26"
124
- iola ask "сделай ссылку Яндекс Go от Медведево, Школьная 15 до Медведево, Советская 20"
124
+ iola ask "сделай ссылку Яндекс Go от Йошкар-Ола, Красноармейская 43 до Йошкар-Ола, Гагарина 8"
125
125
  ```
126
126
 
127
127
  ## Ручная инструкция по ключу геокодера
@@ -211,7 +211,7 @@ QR-код:
211
211
  iola ask "по последнему письму создай встречу завтра в 14:00, сохрани письмо на диск и пришли отправителю ссылку"
212
212
  iola ask "собери полный пакет по контакту Петров: папка на диске, заметка, встреча завтра в 12 и ссылка с QR"
213
213
  iola ask "создай папку для школы 2 на яндекс диске и отправь ссылку контакту Иванов"
214
- iola ask "сделай ссылку Яндекс Go от Медведево, Школьная 15 до Медведево, Советская 20"
214
+ iola ask "сделай ссылку Яндекс Go от Йошкар-Ола, Красноармейская 43 до Йошкар-Ола, Гагарина 8"
215
215
  ```
216
216
 
217
217
  CLI использует уже подключенные сервисы: Почту, Диск, Контакты и Календарь. Если не хватает email, найдено несколько контактов или неясна дата встречи, CLI должен уточнить, а не выбирать случайно.
@@ -47,8 +47,8 @@ iola geo services "Йошкар-Ола, улица Петрова, 15"
47
47
 
48
48
  ```bash
49
49
  iola yandex go status
50
- iola yandex go link --from "Медведево, Школьная 15" --to "Медведево, Советская 20"
51
- iola yandex go open --from "Медведево, Школьная 15" --to "Медведево, Советская 20" --tariff econom
50
+ iola yandex go link --from "Йошкар-Ола, Красноармейская 43" --to "Йошкар-Ола, Гагарина 8"
51
+ iola yandex go open --from "Йошкар-Ола, Красноармейская 43" --to "Йошкар-Ола, Гагарина 8" --tariff econom
52
52
  ```
53
53
 
54
54
  Облачные диски:
@@ -12,57 +12,53 @@ iola master
12
12
 
13
13
  ## Компоненты
14
14
 
15
- ### 1. workspace и контекст
15
+ ```text
16
+ 0. выход в CLI [без настройки] - пропустить мастер
17
+
18
+ Базовая настройка
19
+ 1. Рабочая папка и контекст
20
+ 2. Разрешения и безопасный режим
21
+ 3. 7-Zip / архивы
22
+ 4. Индекс локальных документов
23
+ 5. Браузерный модуль
24
+
25
+ Локальный AI
26
+ 6. IOLA локальная модель
27
+ 7. Ollama
28
+
29
+ Российские AI и сервисы
30
+ 8. GigaChat API
31
+ 9. Yandex Connector
32
+ 10. Yandex Cloud Connector
33
+
34
+ Зарубежные AI
35
+ 11. OpenAI API
36
+ 12. OpenRouter API
37
+
38
+ Codex
39
+ 13. Codex CLI
40
+ 14. Подключение IOLA к Codex
41
+ ```
42
+
43
+ ## Базовая настройка
44
+
45
+ ### 1. Рабочая папка и контекст
16
46
 
17
47
  Создает рабочую среду текущей папки: `.iola/`, `IOLA.md` и `.iola/context.md`.
18
48
 
19
49
  Нужно, если агент будет работать с локальными файлами, документами, задачами, артефактами и контекстом проекта.
20
50
 
21
- ### 2. policy analyst
51
+ ### 2. Разрешения и безопасный режим
22
52
 
23
53
  Включает профиль разрешений для аналитической работы: открытые данные, отчеты, безопасные локальные операции.
24
54
 
25
- ### 3. IOLA локальная модель
26
-
27
- Проверяет штатную локальную модель IOLA и готовит ее к работе через доступный runtime.
28
-
29
- Если модель уже скачана и доступна, пункт показывается как `готово`.
30
-
31
- После настройки локальную модель можно менять в интерактивном агенте через `/model`. Помимо штатной IOLA-модели можно выбрать установленную или рекомендуемую Ollama-модель, либо вручную ввести имя любой модели из библиотеки Ollama.
32
-
33
- ### 4. GigaChat API
34
-
35
- Настраивает профиль GigaChat и сохраняет authorization key локально у пользователя.
36
-
37
- Российский провайдер вызывается напрямую, без gateway/proxy.
38
-
39
- ### 5. OpenAI API
40
-
41
- Настраивает профиль OpenAI и сохраняет API-ключ локально у пользователя.
42
-
43
- После сохранения ключа мастер предлагает выбрать модель из доступного списка.
44
-
45
- ### 6. OpenRouter API
46
-
47
- Настраивает профиль OpenRouter и сохраняет API-ключ локально у пользователя.
48
-
49
- После сохранения ключа мастер предлагает выбрать разработчика моделей OpenRouter, а затем одну из свежих моделей для текстовой работы. В списке моделей `0` возвращает к выбору разработчика.
50
-
51
- ### 7. Codex CLI
52
-
53
- Проверяет наличие Codex CLI и авторизации. Если Codex уже установлен и вход выполнен, пункт показывается как `готово`.
54
-
55
- ### 8. MCP для Codex
56
-
57
- Добавляет MCP-сервер открытых данных Йошкар-Олы в Codex. Этот пункт можно запускать повторно для обновления подключения.
58
-
59
- ### 9. 7-Zip / архивы
55
+ ### 3. 7-Zip / архивы
60
56
 
61
57
  Проверяет 7-Zip. Если архиватор не найден, мастер устанавливает его.
62
58
 
63
59
  Нужен для чтения, распаковки, сборки и индексирования архивов.
64
60
 
65
- ### 10. Индекс локальных документов
61
+ ### 4. Индекс локальных документов
66
62
 
67
63
  Готовит режим чтения файлов и подсказывает команду индексирования локальной папки:
68
64
 
@@ -70,17 +66,35 @@ iola master
70
66
  iola index folder ./docs
71
67
  ```
72
68
 
73
- ### 11. Browser runtime
69
+ ### 5. Браузерный модуль
74
70
 
75
71
  Проверяет Playwright/Chromium runtime. Нужен для браузерного агента.
76
72
 
77
- ### 12. Ollama
73
+ ## Локальный AI
74
+
75
+ ### 6. IOLA локальная модель
76
+
77
+ Проверяет штатную локальную модель IOLA и готовит ее к работе через доступный runtime.
78
+
79
+ Если модель уже скачана и доступна, пункт показывается как `готово`.
80
+
81
+ После настройки локальную модель можно менять в интерактивном агенте через `/model`. Помимо штатной IOLA-модели можно выбрать установленную или рекомендуемую Ollama-модель, либо вручную ввести имя любой модели из библиотеки Ollama.
82
+
83
+ ### 7. Ollama
78
84
 
79
85
  Опциональный локальный runtime для выбора сторонних моделей из библиотеки Ollama.
80
86
 
81
87
  Если runtime уже установлен, пункт показывается как `готово`.
82
88
 
83
- ### 13. Yandex Connector
89
+ ## Российские AI и сервисы
90
+
91
+ ### 8. GigaChat API
92
+
93
+ Настраивает профиль GigaChat и сохраняет authorization key локально у пользователя.
94
+
95
+ Российский провайдер вызывается напрямую, без gateway/proxy.
96
+
97
+ ### 9. Yandex Connector
84
98
 
85
99
  Настраивает единый коннектор пользовательских сервисов Яндекса.
86
100
 
@@ -95,7 +109,7 @@ iola index folder ./docs
95
109
 
96
110
  Инструкция: [Yandex Connector](Yandex-Connector).
97
111
 
98
- ### 14. Yandex Cloud Connector
112
+ ### 10. Yandex Cloud Connector
99
113
 
100
114
  Настраивает Yandex Cloud Connector: геокодер и, при необходимости, YandexGPT.
101
115
 
@@ -107,6 +121,30 @@ iola index folder ./docs
107
121
 
108
122
  Инструкция: [Yandex Cloud Connector](Yandex-Cloud-Connector).
109
123
 
124
+ ## Зарубежные AI
125
+
126
+ ### 11. OpenAI API
127
+
128
+ Настраивает профиль OpenAI и сохраняет API-ключ локально у пользователя.
129
+
130
+ После сохранения ключа мастер предлагает выбрать модель из доступного списка.
131
+
132
+ ### 12. OpenRouter API
133
+
134
+ Настраивает профиль OpenRouter и сохраняет API-ключ локально у пользователя.
135
+
136
+ После сохранения ключа мастер предлагает выбрать разработчика моделей OpenRouter, а затем одну из свежих моделей для текстовой работы. В списке моделей `0` возвращает к выбору разработчика.
137
+
138
+ ## Codex
139
+
140
+ ### 13. Codex CLI
141
+
142
+ Проверяет наличие Codex CLI и авторизации. Если Codex уже установлен и вход выполнен, пункт показывается как `готово`.
143
+
144
+ ### 14. Подключение IOLA к Codex
145
+
146
+ Добавляет MCP-сервер открытых данных Йошкар-Олы в Codex. Этот пункт можно запускать повторно для обновления подключения.
147
+
110
148
  ## Повторный запуск
111
149
 
112
150
  Если компонент уже настроен, его можно не выбирать. Если нужно переустановить или обновить компонент, выберите его номер вручную.
@@ -395,8 +395,8 @@ CLI не должен сам нажимать финальные кнопки в
395
395
  Команды:
396
396
 
397
397
  ```bash
398
- iola yandex go link --from "Медведево, Школьная 15" --to "Медведево, Советская 20"
399
- iola yandex go open --from "Медведево, Школьная 15" --to "Медведево, Советская 20" --tariff econom
398
+ iola yandex go link --from "Йошкар-Ола, Красноармейская 43" --to "Йошкар-Ола, Гагарина 8"
399
+ iola yandex go open --from "Йошкар-Ола, Красноармейская 43" --to "Йошкар-Ола, Гагарина 8" --tariff econom
400
400
  ```
401
401
 
402
402
  Если ключ геокодера не подключен, CLI должен объяснить, что нужно открыть `/master` и выбрать `Yandex Cloud Connector (геокодинг и YandexGPT)`, либо запустить `iola yandex cloud setup`.