@iola_adm/iola-cli 0.2.12 → 0.2.14
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 +2 -1
- package/package.json +1 -1
- package/src/cli.js +114 -19
- package/test/smoke-test.js +5 -0
- package/wiki/Yandex-Connector.md +18 -5
- package/wiki//320/232/320/276/320/274/320/260/320/275/320/264/321/213.md +1 -0
- package/wiki//320/234/320/260/321/201/321/202/320/265/321/200-/320/275/320/260/321/201/321/202/321/200/320/276/320/271/320/272/320/270.md +2 -0
package/README.md
CHANGED
|
@@ -188,11 +188,12 @@ iola cloud backup
|
|
|
188
188
|
|
|
189
189
|
Инструкция: [Облачные диски](https://github.com/adm-iola/iola-cli/wiki/Облачные-диски).
|
|
190
190
|
|
|
191
|
-
Yandex Connector
|
|
191
|
+
Yandex Connector при подключении запрашивает максимальный набор OAuth-прав для пользовательских сервисов Яндекса. Какие функции CLI реально использует, выбирается отдельно:
|
|
192
192
|
|
|
193
193
|
```bash
|
|
194
194
|
iola yandex services
|
|
195
195
|
iola yandex setup
|
|
196
|
+
iola yandex menu
|
|
196
197
|
iola yandex status
|
|
197
198
|
```
|
|
198
199
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -348,6 +348,7 @@ const DEFAULT_AI_CONFIG = {
|
|
|
348
348
|
},
|
|
349
349
|
},
|
|
350
350
|
yandex: {
|
|
351
|
+
authorizedServices: [],
|
|
351
352
|
enabledServices: [],
|
|
352
353
|
categories: {},
|
|
353
354
|
oauth: {
|
|
@@ -440,6 +441,7 @@ const SLASH_COMMANDS = [
|
|
|
440
441
|
{ command: "/tools", description: "tools и toolsets" },
|
|
441
442
|
{ command: "/files status", description: "локальные файловые операции" },
|
|
442
443
|
{ command: "/cloud status", description: "облачные диски" },
|
|
444
|
+
{ command: "/yandex", description: "выбор сервисов Yandex Connector" },
|
|
443
445
|
{ command: "/archive doctor", description: "архиватор" },
|
|
444
446
|
{ command: "/changes list", description: "подготовленные изменения" },
|
|
445
447
|
{ command: "/index status", description: "индекс документов" },
|
|
@@ -707,7 +709,7 @@ Usage:
|
|
|
707
709
|
iola tools list|toolsets|enable|disable|profile
|
|
708
710
|
iola files status|mode|approvals|tree|read|search|write|patch
|
|
709
711
|
iola cloud setup|status|ls|find|upload|download|share|save|backup
|
|
710
|
-
iola yandex setup|status|services|enable|disable|oauth-url|token
|
|
712
|
+
iola yandex setup|menu|status|services|enable|disable|oauth-url|token
|
|
711
713
|
iola archive doctor|list|test|extract|create|index
|
|
712
714
|
iola changes list|show|apply|discard
|
|
713
715
|
iola import file|folder
|
|
@@ -1446,6 +1448,7 @@ async function handleAgentLine(line, state) {
|
|
|
1446
1448
|
skills: ["skills", args],
|
|
1447
1449
|
files: ["files", args],
|
|
1448
1450
|
archive: ["archive", args],
|
|
1451
|
+
yandex: ["yandex", args.length ? args : ["menu"]],
|
|
1449
1452
|
changes: ["changes", args],
|
|
1450
1453
|
index: ["index", args],
|
|
1451
1454
|
reports: ["reports", args],
|
|
@@ -2019,6 +2022,7 @@ async function doctor(args = []) {
|
|
|
2019
2022
|
openrouterKey: process.env.OPENROUTER_API_KEY ? "env" : secrets.openrouter?.apiKey ? "local" : "missing",
|
|
2020
2023
|
yandexGeocoderKey: (process.env.YANDEX_GEOCODER_API_KEY || process.env.YANDEX_MAPS_API_KEY) ? "env" : secrets.yandexGeocoder?.apiKey ? "local" : "missing",
|
|
2021
2024
|
yandexConnector: (process.env.YANDEX_OAUTH_TOKEN || secrets.yandex?.oauthToken || secrets.cloud?.["yandex-disk"]?.token) ? "local/env" : "missing",
|
|
2025
|
+
yandexAuthorized: config.yandex?.authorizedServices?.join(", ") || "-",
|
|
2022
2026
|
yandexServices: config.yandex?.enabledServices?.join(", ") || (secrets.cloud?.["yandex-disk"]?.token ? "disk (legacy cloud token)" : "-"),
|
|
2023
2027
|
ollama: diagnostics.ollama.installed ? diagnostics.ollama.version : "not-installed",
|
|
2024
2028
|
},
|
|
@@ -2398,6 +2402,7 @@ async function handleUninstall(args = []) {
|
|
|
2398
2402
|
description: "локальная папка .iola текущего проекта",
|
|
2399
2403
|
});
|
|
2400
2404
|
}
|
|
2405
|
+
targets.push(...getIolaTempCleanupTargets());
|
|
2401
2406
|
const npmPackage = "@iola_adm/iola-cli";
|
|
2402
2407
|
|
|
2403
2408
|
const safeTargets = targets.map((target) => ({
|
|
@@ -2405,10 +2410,12 @@ async function handleUninstall(args = []) {
|
|
|
2405
2410
|
path: path.resolve(target.path),
|
|
2406
2411
|
}));
|
|
2407
2412
|
const home = path.resolve(os.homedir());
|
|
2413
|
+
const temp = path.resolve(os.tmpdir());
|
|
2408
2414
|
for (const target of safeTargets) {
|
|
2409
2415
|
const isUserConfig = target.path === path.resolve(CONFIG_DIR) && target.path.startsWith(home);
|
|
2410
2416
|
const isProjectConfig = target.path === path.resolve(PROJECT_IOLA_DIR) && target.path.startsWith(path.resolve(process.cwd()));
|
|
2411
|
-
|
|
2417
|
+
const isTemp = target.path.startsWith(temp + path.sep) && path.basename(target.path).startsWith("iola-");
|
|
2418
|
+
if (!isUserConfig && !isProjectConfig && !isTemp) {
|
|
2412
2419
|
throw new Error(`Небезопасный путь удаления: ${target.path}`);
|
|
2413
2420
|
}
|
|
2414
2421
|
}
|
|
@@ -2472,10 +2479,34 @@ async function handleUninstall(args = []) {
|
|
|
2472
2479
|
return { deleted: true };
|
|
2473
2480
|
}
|
|
2474
2481
|
|
|
2482
|
+
function getIolaTempCleanupTargets() {
|
|
2483
|
+
const tempDir = os.tmpdir();
|
|
2484
|
+
const names = [
|
|
2485
|
+
"iola-cli-test",
|
|
2486
|
+
"iola-model-check.txt",
|
|
2487
|
+
];
|
|
2488
|
+
let dynamicNames = [];
|
|
2489
|
+
try {
|
|
2490
|
+
dynamicNames = readdirSync(tempDir)
|
|
2491
|
+
.filter((name) => /^iola-(archive|codex|browser)-/u.test(name))
|
|
2492
|
+
.slice(0, 100);
|
|
2493
|
+
} catch {
|
|
2494
|
+
dynamicNames = [];
|
|
2495
|
+
}
|
|
2496
|
+
return [...new Set([...names, ...dynamicNames])].map((name) => ({
|
|
2497
|
+
label: "temp",
|
|
2498
|
+
path: path.join(tempDir, name),
|
|
2499
|
+
description: "временные файлы iola-cli",
|
|
2500
|
+
}));
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2475
2503
|
async function removeGlobalNpmPackage(npmPackage) {
|
|
2476
2504
|
if (process.platform === "win32") {
|
|
2477
2505
|
const command = quoteWindowsCommand(getNpmCommand(), ["remove", "-g", npmPackage]);
|
|
2478
|
-
const
|
|
2506
|
+
const cleanupConfig = quoteWindowsCommand("rmdir", ["/s", "/q", CONFIG_DIR]);
|
|
2507
|
+
const cleanupTempTest = quoteWindowsCommand("rmdir", ["/s", "/q", path.join(os.tmpdir(), "iola-cli-test")]);
|
|
2508
|
+
const cleanupTempModel = quoteWindowsCommand("del", ["/f", "/q", path.join(os.tmpdir(), "iola-model-check.txt")]);
|
|
2509
|
+
const script = `ping 127.0.0.1 -n 3 > nul & ${cleanupConfig} 2> nul & ${cleanupTempTest} 2> nul & ${cleanupTempModel} 2> nul & ${command}`;
|
|
2479
2510
|
const child = spawn(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", script], {
|
|
2480
2511
|
detached: true,
|
|
2481
2512
|
stdio: "ignore",
|
|
@@ -3173,9 +3204,14 @@ async function handleCloud(args) {
|
|
|
3173
3204
|
}
|
|
3174
3205
|
|
|
3175
3206
|
async function handleYandex(args) {
|
|
3176
|
-
const [action = "status", target, ...rest] = args;
|
|
3207
|
+
const [action = process.stdin.isTTY ? "menu" : "status", target, ...rest] = args;
|
|
3177
3208
|
const options = parseOptions(rest);
|
|
3178
3209
|
|
|
3210
|
+
if (action === "menu" || action === "choose" || action === "select") {
|
|
3211
|
+
await chooseYandexServicesMenu();
|
|
3212
|
+
return;
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3179
3215
|
if (action === "services" || action === "list") {
|
|
3180
3216
|
printYandexServices();
|
|
3181
3217
|
return;
|
|
@@ -3223,6 +3259,7 @@ async function handleYandex(args) {
|
|
|
3223
3259
|
|
|
3224
3260
|
throw new Error(`Команды yandex:
|
|
3225
3261
|
iola yandex setup
|
|
3262
|
+
iola yandex menu
|
|
3226
3263
|
iola yandex status|doctor
|
|
3227
3264
|
iola yandex services
|
|
3228
3265
|
iola yandex enable disk mail calendar
|
|
@@ -3257,17 +3294,10 @@ function printYandexServices(options = {}) {
|
|
|
3257
3294
|
async function setupYandexConnector(args = []) {
|
|
3258
3295
|
const options = parseOptions(args);
|
|
3259
3296
|
const config = await loadConfig();
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
printYandexServices();
|
|
3265
|
-
const answer = await askText("Сервисы через запятую [identity,disk]: ");
|
|
3266
|
-
services = normalizeYandexServiceList(answer.trim() ? answer.split(/[,\s]+/) : ["identity", "disk"]);
|
|
3267
|
-
}
|
|
3268
|
-
|
|
3269
|
-
if (services.length === 0) services = ["identity", "disk"];
|
|
3270
|
-
await saveYandexEnabledServices(services);
|
|
3297
|
+
const authorizedServices = getYandexOAuthCapableServiceIds();
|
|
3298
|
+
const enabledServices = config.yandex?.enabledServices?.length ? config.yandex.enabledServices : ["identity", "disk"];
|
|
3299
|
+
await saveYandexAuthorizedServices(authorizedServices);
|
|
3300
|
+
await saveYandexEnabledServices(enabledServices);
|
|
3271
3301
|
|
|
3272
3302
|
const clientId = options["client-id"] || config.yandex?.oauth?.clientId || (process.stdin.isTTY ? (await askText("Yandex OAuth Client ID [Enter - пропустить]: ")).trim() : "");
|
|
3273
3303
|
if (clientId) {
|
|
@@ -3280,9 +3310,11 @@ async function setupYandexConnector(args = []) {
|
|
|
3280
3310
|
}
|
|
3281
3311
|
|
|
3282
3312
|
console.log("Yandex Connector настроен.");
|
|
3283
|
-
console.log(
|
|
3313
|
+
console.log(`Запрошены максимальные OAuth-права: ${authorizedServices.join(", ")}`);
|
|
3314
|
+
console.log(`Активные функции CLI: ${normalizeYandexServiceList(enabledServices).join(", ")}`);
|
|
3315
|
+
console.log("Выбрать активные функции можно командой /yandex или iola yandex menu.");
|
|
3284
3316
|
if (clientId) {
|
|
3285
|
-
const url = buildYandexOAuthUrl({ clientId, services });
|
|
3317
|
+
const url = buildYandexOAuthUrl({ clientId, services: authorizedServices });
|
|
3286
3318
|
console.log("Откройте ссылку авторизации, получите OAuth-токен и сохраните его командой: iola yandex token set");
|
|
3287
3319
|
console.log(url);
|
|
3288
3320
|
if (options.open) await openUrl(url);
|
|
@@ -3291,6 +3323,46 @@ async function setupYandexConnector(args = []) {
|
|
|
3291
3323
|
}
|
|
3292
3324
|
}
|
|
3293
3325
|
|
|
3326
|
+
async function chooseYandexServicesMenu() {
|
|
3327
|
+
if (!process.stdin.isTTY) {
|
|
3328
|
+
await printYandexConnectorStatus();
|
|
3329
|
+
return;
|
|
3330
|
+
}
|
|
3331
|
+
const config = await loadConfig();
|
|
3332
|
+
const serviceIds = Object.keys(YANDEX_CONNECTOR_SERVICES);
|
|
3333
|
+
const enabled = new Set(config.yandex?.enabledServices?.length ? config.yandex.enabledServices : ["identity", "disk"]);
|
|
3334
|
+
console.log("Yandex Connector: выберите сервисы.");
|
|
3335
|
+
serviceIds.forEach((id, index) => {
|
|
3336
|
+
const service = YANDEX_CONNECTOR_SERVICES[id];
|
|
3337
|
+
const marker = enabled.has(id) ? "✓" : " ";
|
|
3338
|
+
console.log(`${index + 1}. [${marker}] ${service.title} (${id}, ${service.status}) - ${service.hint}`);
|
|
3339
|
+
});
|
|
3340
|
+
console.log("0. Отмена");
|
|
3341
|
+
const defaults = serviceIds.map((id, index) => enabled.has(id) ? String(index + 1) : "").filter(Boolean);
|
|
3342
|
+
const answer = (await askText(`Номера через запятую [${defaults.join(",") || "1,2"}]: `)).trim();
|
|
3343
|
+
if (answer === "0") {
|
|
3344
|
+
console.log("Выбор сервисов отменен.");
|
|
3345
|
+
return;
|
|
3346
|
+
}
|
|
3347
|
+
const selectedNumbers = answer ? answer.split(/[,\s]+/).filter(Boolean) : (defaults.length ? defaults : ["1", "2"]);
|
|
3348
|
+
const selected = selectedNumbers.map((item) => {
|
|
3349
|
+
const index = Number(item) - 1;
|
|
3350
|
+
if (!Number.isInteger(index) || index < 0 || index >= serviceIds.length) {
|
|
3351
|
+
throw new Error(`Неизвестный номер сервиса: ${item}`);
|
|
3352
|
+
}
|
|
3353
|
+
return serviceIds[index];
|
|
3354
|
+
});
|
|
3355
|
+
await saveYandexEnabledServices(selected);
|
|
3356
|
+
console.log(`Включены сервисы: ${normalizeYandexServiceList(selected).join(", ")}`);
|
|
3357
|
+
const nextConfig = await loadConfig();
|
|
3358
|
+
if (nextConfig.yandex?.oauth?.clientId) {
|
|
3359
|
+
console.log("OAuth-ссылка с максимальными правами коннектора:");
|
|
3360
|
+
console.log(await buildYandexOAuthUrlFromConfig([]));
|
|
3361
|
+
} else {
|
|
3362
|
+
console.log("Для авторизации создайте OAuth Client ID и выполните: iola yandex oauth-url --client-id CLIENT_ID");
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3294
3366
|
async function updateYandexEnabledServices(rawServices, enabled) {
|
|
3295
3367
|
const config = await loadConfig();
|
|
3296
3368
|
const current = new Set(config.yandex?.enabledServices || []);
|
|
@@ -3320,12 +3392,23 @@ async function saveYandexEnabledServices(services) {
|
|
|
3320
3392
|
});
|
|
3321
3393
|
}
|
|
3322
3394
|
|
|
3395
|
+
async function saveYandexAuthorizedServices(services) {
|
|
3396
|
+
const config = await loadConfig();
|
|
3397
|
+
const normalized = normalizeYandexServiceList(services.length ? services : getYandexOAuthCapableServiceIds());
|
|
3398
|
+
await saveConfig({
|
|
3399
|
+
yandex: {
|
|
3400
|
+
...(config.yandex || {}),
|
|
3401
|
+
authorizedServices: normalized,
|
|
3402
|
+
},
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3323
3406
|
async function buildYandexOAuthUrlFromConfig(rawArgs = []) {
|
|
3324
3407
|
const options = parseOptions(rawArgs);
|
|
3325
3408
|
const config = await loadConfig();
|
|
3326
3409
|
const clientId = options["client-id"] || config.yandex?.oauth?.clientId;
|
|
3327
3410
|
if (!clientId) throw new Error("Yandex OAuth Client ID не задан. Пример: iola yandex oauth-url disk --client-id CLIENT_ID");
|
|
3328
|
-
const services = normalizeYandexServiceList(options._.length ? options._ : (config.yandex?.
|
|
3411
|
+
const services = normalizeYandexServiceList(options._.length ? options._ : (config.yandex?.authorizedServices?.length ? config.yandex.authorizedServices : getYandexOAuthCapableServiceIds()));
|
|
3329
3412
|
return buildYandexOAuthUrl({ clientId, services });
|
|
3330
3413
|
}
|
|
3331
3414
|
|
|
@@ -3350,6 +3433,12 @@ function getYandexScopesForServices(services) {
|
|
|
3350
3433
|
return [...scopes].join(" ");
|
|
3351
3434
|
}
|
|
3352
3435
|
|
|
3436
|
+
function getYandexOAuthCapableServiceIds() {
|
|
3437
|
+
return Object.entries(YANDEX_CONNECTOR_SERVICES)
|
|
3438
|
+
.filter(([, service]) => service.scope)
|
|
3439
|
+
.map(([id]) => id);
|
|
3440
|
+
}
|
|
3441
|
+
|
|
3353
3442
|
async function setYandexConnectorToken(args = []) {
|
|
3354
3443
|
const options = parseOptions(args);
|
|
3355
3444
|
const token = options.token || (process.stdin.isTTY ? (await askText("Yandex OAuth token: ")).trim() : "");
|
|
@@ -3379,6 +3468,7 @@ async function deleteYandexConnectorToken() {
|
|
|
3379
3468
|
async function printYandexConnectorStatus(options = {}) {
|
|
3380
3469
|
const [config, secrets] = await Promise.all([loadConfig(), loadSecrets()]);
|
|
3381
3470
|
const enabled = config.yandex?.enabledServices || [];
|
|
3471
|
+
const authorized = config.yandex?.authorizedServices?.length ? config.yandex.authorizedServices : [];
|
|
3382
3472
|
const legacyDiskToken = Boolean(secrets.cloud?.["yandex-disk"]?.token && !secrets.yandex?.oauthToken);
|
|
3383
3473
|
const token = process.env.YANDEX_OAUTH_TOKEN || secrets.yandex?.oauthToken || secrets.cloud?.["yandex-disk"]?.token || "";
|
|
3384
3474
|
const rows = Object.entries(YANDEX_CONNECTOR_SERVICES).map(([id, service]) => ({
|
|
@@ -3386,7 +3476,8 @@ async function printYandexConnectorStatus(options = {}) {
|
|
|
3386
3476
|
enabled: enabled.includes(id) ? "yes" : (legacyDiskToken && id === "disk" ? "legacy" : "no"),
|
|
3387
3477
|
category: service.category,
|
|
3388
3478
|
status: service.status,
|
|
3389
|
-
token: service.scope && (enabled.includes(id) || (legacyDiskToken && id === "disk")) ? (token ? "local/env" : "missing") : "-",
|
|
3479
|
+
token: service.scope && (authorized.includes(id) || enabled.includes(id) || (legacyDiskToken && id === "disk")) ? (token ? "local/env" : "missing") : "-",
|
|
3480
|
+
authorized: authorized.includes(id) ? "yes" : "-",
|
|
3390
3481
|
title: service.title,
|
|
3391
3482
|
}));
|
|
3392
3483
|
printTable(rows, [
|
|
@@ -3394,6 +3485,7 @@ async function printYandexConnectorStatus(options = {}) {
|
|
|
3394
3485
|
["enabled", "Вкл"],
|
|
3395
3486
|
["category", "Категория"],
|
|
3396
3487
|
["status", "Статус"],
|
|
3488
|
+
["authorized", "Права"],
|
|
3397
3489
|
["token", "Токен"],
|
|
3398
3490
|
["title", "Сервис"],
|
|
3399
3491
|
]);
|
|
@@ -13192,6 +13284,9 @@ function validateConfig(config) {
|
|
|
13192
13284
|
for (const service of config.yandex?.enabledServices || []) {
|
|
13193
13285
|
if (!YANDEX_CONNECTOR_SERVICES[service]) errors.push(`yandex.enabledServices содержит неизвестный сервис: ${service}`);
|
|
13194
13286
|
}
|
|
13287
|
+
for (const service of config.yandex?.authorizedServices || []) {
|
|
13288
|
+
if (!YANDEX_CONNECTOR_SERVICES[service]) errors.push(`yandex.authorizedServices содержит неизвестный сервис: ${service}`);
|
|
13289
|
+
}
|
|
13195
13290
|
return errors;
|
|
13196
13291
|
}
|
|
13197
13292
|
|
package/test/smoke-test.js
CHANGED
|
@@ -57,10 +57,15 @@ assertIncludes(cliSource, "isOpenAiTextGenerationModel", "OpenAI model selection
|
|
|
57
57
|
assertIncludes(cliSource, "dedupeDatedOpenAiModels", "OpenAI model selection should hide dated duplicates when aliases exist");
|
|
58
58
|
assertIncludes(cliSource, "chooseLocalModel", "Local model selection should support IOLA and Ollama models");
|
|
59
59
|
assertIncludes(cliSource, "Другая Ollama-модель", "Local model selection should allow manual Ollama model names");
|
|
60
|
+
assertIncludes(cliSource, "chooseYandexServicesMenu", "Yandex Connector should have a service selection menu");
|
|
61
|
+
assertIncludes(cliSource, "Запрошены максимальные OAuth-права", "Yandex setup should request maximum connector permissions");
|
|
62
|
+
assertIncludes(cliSource, "Выбрать активные функции можно командой /yandex", "Yandex setup should direct service selection to /yandex");
|
|
63
|
+
assertNotIncludes(cliSource, "Сервисы через запятую [identity,disk]", "Yandex setup should not ask for services during connector setup");
|
|
60
64
|
|
|
61
65
|
const commands = await runCli(["commands"]);
|
|
62
66
|
assertIncludes(commands, "iola browser status|install|open|text|html|screenshot|pdf|click|type|eval", "commands");
|
|
63
67
|
assertIncludes(commands, "iola mcp list|status|install|remove|serve [--stdio]", "commands");
|
|
68
|
+
assertIncludes(commands, "iola yandex setup|menu|status|services|enable|disable|oauth-url|token", "commands");
|
|
64
69
|
assertIncludes(commands, "iola delete", "commands");
|
|
65
70
|
assertNotIncludes(commands, "iola uninstall", "commands");
|
|
66
71
|
assertNotIncludes(commands, "Госуслуг", "commands");
|
package/wiki/Yandex-Connector.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`Yandex Connector` - единая точка подключения пользовательских сервисов Яндекса в `iola-cli`.
|
|
4
4
|
|
|
5
|
-
Цель: пользователь один раз настраивает вход через
|
|
5
|
+
Цель: пользователь один раз настраивает вход через Яндекс с максимальным набором OAuth-прав, а CLI хранит токен локально. Какие функции CLI реально использует, пользователь выбирает отдельно через `/yandex`.
|
|
6
6
|
|
|
7
7
|
Секреты сохраняются только на компьютере пользователя в `~/.iola/secrets.json`. Они не отправляются на сервер IOLA и не попадают в `iola cloud backup`.
|
|
8
8
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
```bash
|
|
12
12
|
iola yandex services
|
|
13
13
|
iola yandex setup
|
|
14
|
+
iola yandex menu
|
|
14
15
|
iola yandex status
|
|
15
16
|
iola yandex doctor
|
|
16
17
|
iola yandex enable disk mail calendar
|
|
@@ -57,13 +58,13 @@ Backlog после первого контура:
|
|
|
57
58
|
- `cloud_api:disk.read`;
|
|
58
59
|
- `cloud_api:disk.write`;
|
|
59
60
|
- `cloud_api:disk.info`.
|
|
60
|
-
3.
|
|
61
|
+
3. Запустите подключение. Оно не спрашивает список сервисов, а готовит OAuth-ссылку с максимальным набором прав коннектора:
|
|
61
62
|
|
|
62
63
|
```bash
|
|
63
|
-
iola yandex setup
|
|
64
|
+
iola yandex setup --client-id CLIENT_ID
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
4. Откройте ссылку авторизации, которую выведет CLI.
|
|
67
|
+
4. Откройте ссылку авторизации, которую выведет CLI. В ней будут запрошены максимальные права для поддерживаемых пользовательских сервисов Яндекса.
|
|
67
68
|
5. Скопируйте OAuth-токен.
|
|
68
69
|
6. Сохраните токен:
|
|
69
70
|
|
|
@@ -71,7 +72,19 @@ iola yandex setup disk --client-id CLIENT_ID
|
|
|
71
72
|
iola yandex token set
|
|
72
73
|
```
|
|
73
74
|
|
|
74
|
-
7.
|
|
75
|
+
7. Выберите, какие функции CLI реально использует:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
iola yandex menu
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
В интерактивном CLI это же меню открывается slash-командой:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
/yandex
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
8. Проверьте:
|
|
75
88
|
|
|
76
89
|
```bash
|
|
77
90
|
iola yandex doctor
|
|
@@ -114,6 +114,8 @@ iola index folder ./docs
|
|
|
114
114
|
- Yandex ID;
|
|
115
115
|
- Яндекс Диск.
|
|
116
116
|
|
|
117
|
+
Мастер не спрашивает список сервисов. Он подключает коннектор с максимальным набором OAuth-прав, а активные функции CLI выбираются позже командой `/yandex` в интерактивном CLI или `iola yandex menu` в терминале.
|
|
118
|
+
|
|
117
119
|
В коннектор также заложены категории для проверки: Почта, Календарь, Контакты, Wiki, Tracker, Forms, Документы/360. Такси, Маркет и Доставка записаны в backlog только как подготовка ссылки, маршрута или списка без заказа и оплаты.
|
|
118
120
|
|
|
119
121
|
Инструкция: [Yandex Connector](Yandex-Connector).
|