@iola_adm/iola-cli 0.2.7 → 0.2.9
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 +1 -0
- package/package.json +1 -1
- package/skills/personal-docs/SKILL.md +1 -0
- package/src/cli.js +176 -9
- package/wiki//320/232/320/276/320/274/320/260/320/275/320/264/321/213.md +1 -0
- package/wiki//320/236/320/261/320/273/320/260/321/207/320/275/321/213/320/265-/320/264/320/270/321/201/320/272/320/270.md +62 -7
- package/wiki//320/241/320/272/320/270/320/273/320/273/321/213-/320/264/320/273/321/217-/320/266/320/270/321/202/320/265/320/273/320/265/320/271.md +9 -0
package/README.md
CHANGED
|
@@ -179,6 +179,7 @@ iola geo services "Йошкар-Ола, улица Петрова, 15"
|
|
|
179
179
|
iola cloud setup yandex-disk
|
|
180
180
|
iola cloud setup mailru-cloud
|
|
181
181
|
iola cloud status
|
|
182
|
+
iola cloud mkdir /IOLA/Фото
|
|
182
183
|
iola cloud find "справка" --path /IOLA
|
|
183
184
|
iola cloud upload report.md /IOLA/reports/report.md
|
|
184
185
|
iola cloud share /IOLA/reports/report.md
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ description: Личные документы пользователя в обл
|
|
|
12
12
|
Основные сценарии:
|
|
13
13
|
|
|
14
14
|
- `cloud-find-document` - найти документ в подключенном облаке.
|
|
15
|
+
- `cloud-create-folder` - создать папку на подключенном облачном диске.
|
|
15
16
|
- `cloud-save-result` - сохранить ответ, отчет, карточку или список в облако.
|
|
16
17
|
- `cloud-share-link` - создать публичную ссылку на файл в Яндекс Диске.
|
|
17
18
|
- `cloud-document-pack` - собрать папку с материалами для обращения.
|
package/src/cli.js
CHANGED
|
@@ -2948,6 +2948,14 @@ async function handleCloud(args) {
|
|
|
2948
2948
|
return;
|
|
2949
2949
|
}
|
|
2950
2950
|
|
|
2951
|
+
if (action === "mkdir" || action === "create-folder") {
|
|
2952
|
+
const provider = await getCloudProvider(options.provider);
|
|
2953
|
+
const remotePath = target || `${cloudRootForProvider(provider)}/Новая папка`;
|
|
2954
|
+
const result = await cloudCreateFolder(provider, remotePath);
|
|
2955
|
+
printKeyValue(result);
|
|
2956
|
+
return;
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2951
2959
|
if (action === "upload") {
|
|
2952
2960
|
if (!target) throw new Error('Пример: iola cloud upload report.md /IOLA/reports/report.md');
|
|
2953
2961
|
const provider = await getCloudProvider(options.provider);
|
|
@@ -3004,6 +3012,7 @@ async function handleCloud(args) {
|
|
|
3004
3012
|
iola cloud status|doctor
|
|
3005
3013
|
iola cloud use yandex-disk
|
|
3006
3014
|
iola cloud ls /IOLA
|
|
3015
|
+
iola cloud mkdir /IOLA/Фото
|
|
3007
3016
|
iola cloud find "справка" --path /IOLA
|
|
3008
3017
|
iola cloud upload local.txt /IOLA/local.txt
|
|
3009
3018
|
iola cloud download /IOLA/local.txt ./local.txt
|
|
@@ -3116,6 +3125,18 @@ async function cloudFind(provider, query, options = {}) {
|
|
|
3116
3125
|
throw new Error(`Провайдер не поддерживается: ${provider}`);
|
|
3117
3126
|
}
|
|
3118
3127
|
|
|
3128
|
+
async function cloudCreateFolder(provider, remotePath) {
|
|
3129
|
+
if (provider === "yandex-disk") {
|
|
3130
|
+
await ensureYandexDiskDir(remotePath, { allowExisting: true });
|
|
3131
|
+
return { provider, path: normalizeYandexDiskPath(remotePath), status: "created-or-exists" };
|
|
3132
|
+
}
|
|
3133
|
+
if (provider === "mailru-cloud") {
|
|
3134
|
+
await ensureMailruCloudDir(remotePath);
|
|
3135
|
+
return { provider, path: remotePath, status: "created-or-exists" };
|
|
3136
|
+
}
|
|
3137
|
+
throw new Error(`Провайдер не поддерживается: ${provider}`);
|
|
3138
|
+
}
|
|
3139
|
+
|
|
3119
3140
|
async function cloudShare(provider, remotePath) {
|
|
3120
3141
|
if (provider === "yandex-disk") return yandexDiskShare(remotePath);
|
|
3121
3142
|
throw new Error("Публичные ссылки через CLI сейчас поддерживаются только для Яндекс Диска.");
|
|
@@ -3159,19 +3180,31 @@ async function yandexDiskList(remotePath, options = {}) {
|
|
|
3159
3180
|
}
|
|
3160
3181
|
|
|
3161
3182
|
async function yandexDiskFind(query, options = {}) {
|
|
3162
|
-
const payload = await yandexDiskRequest("GET", "/resources/files", { query: { limit: Math.max(100, Number(options.limit || 50) * 5), fields: "items.name,items.path,items.size,items.type" } });
|
|
3163
3183
|
const needle = normalizeGeoText(query);
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
type: item.type === "dir" ? "dir" : "file",
|
|
3167
|
-
name: item.name || path.basename(item.path || ""),
|
|
3168
|
-
path: denormalizeYandexDiskPath(item.path || ""),
|
|
3169
|
-
size: item.size || "-",
|
|
3170
|
-
}))
|
|
3184
|
+
const rows = await yandexDiskListRecursive(options.path || CLOUD_DEFAULT_REMOTE_DIR, { depth: Number(options.depth || 4), limit: Math.max(100, Number(options.limit || 50) * 5) });
|
|
3185
|
+
return rows
|
|
3171
3186
|
.filter((item) => normalizeGeoText(`${item.name} ${item.path}`).includes(needle))
|
|
3172
3187
|
.slice(0, Number(options.limit || 50));
|
|
3173
3188
|
}
|
|
3174
3189
|
|
|
3190
|
+
async function yandexDiskListRecursive(remotePath, options = {}) {
|
|
3191
|
+
const depth = Number(options.depth || 4);
|
|
3192
|
+
const limit = Number(options.limit || 200);
|
|
3193
|
+
const rows = [];
|
|
3194
|
+
await yandexDiskWalk(remotePath, rows, depth, limit);
|
|
3195
|
+
return rows;
|
|
3196
|
+
}
|
|
3197
|
+
|
|
3198
|
+
async function yandexDiskWalk(remotePath, rows, depth, limit) {
|
|
3199
|
+
if (rows.length >= limit || depth < 0) return;
|
|
3200
|
+
const items = await yandexDiskList(remotePath).catch(() => []);
|
|
3201
|
+
for (const item of items) {
|
|
3202
|
+
if (rows.length >= limit) break;
|
|
3203
|
+
rows.push(item);
|
|
3204
|
+
if (item.type === "dir") await yandexDiskWalk(item.path, rows, depth - 1, limit);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3175
3208
|
async function yandexDiskUpload(localPath, remotePath, options = {}) {
|
|
3176
3209
|
const resolved = path.resolve(localPath);
|
|
3177
3210
|
const info = await stat(resolved);
|
|
@@ -7861,6 +7894,20 @@ async function aiAsk(args, context = {}) {
|
|
|
7861
7894
|
const historyEnabled = !options.bare && !options["no-history"] && isFeatureEnabled("sqlite-history");
|
|
7862
7895
|
const sessionId = historyEnabled && isFeatureEnabled("sessions") ? ensureSessionForAsk(options, providerConfig, question) : null;
|
|
7863
7896
|
const history = context.history || (sessionId ? getSessionAiHistory(sessionId) : []);
|
|
7897
|
+
const cloudAnswer = await buildCloudDirectAnswer(question);
|
|
7898
|
+
if (cloudAnswer) {
|
|
7899
|
+
if (historyEnabled) {
|
|
7900
|
+
recordAskHistory({ question, answer: cloudAnswer, providerConfig, dataContext, error: "", sessionId });
|
|
7901
|
+
appendSessionExchange(sessionId, question, cloudAnswer, dataContext, "");
|
|
7902
|
+
}
|
|
7903
|
+
emitEvent(options, "answer", { length: cloudAnswer.length, sessionId, direct: true, cloud: true });
|
|
7904
|
+
if (options.output) {
|
|
7905
|
+
await assertPermission("writeFiles");
|
|
7906
|
+
await writeFile(options.output, cloudAnswer, "utf8");
|
|
7907
|
+
}
|
|
7908
|
+
if (!options.quiet) console.log(cloudAnswer);
|
|
7909
|
+
return cloudAnswer;
|
|
7910
|
+
}
|
|
7864
7911
|
const geoAnswer = await buildGeoDirectAnswer(question);
|
|
7865
7912
|
if (geoAnswer) {
|
|
7866
7913
|
if (historyEnabled) {
|
|
@@ -7961,6 +8008,119 @@ async function buildDirectDataAnswer(question, dataContext) {
|
|
|
7961
8008
|
].join("\n");
|
|
7962
8009
|
}
|
|
7963
8010
|
|
|
8011
|
+
async function buildCloudDirectAnswer(question) {
|
|
8012
|
+
if (!isCloudQuestion(question)) return "";
|
|
8013
|
+
const normalized = String(question || "").toLocaleLowerCase("ru-RU");
|
|
8014
|
+
try {
|
|
8015
|
+
const provider = await getCloudProvider();
|
|
8016
|
+
if (/(созда|сдела|добав).{0,30}(папк|директор)/iu.test(normalized) || /(папк|директор).{0,30}(созда|сдела|добав)/iu.test(normalized)) {
|
|
8017
|
+
const folderName = extractCloudFolderName(question) || "Новая папка";
|
|
8018
|
+
const remotePath = normalizeCloudUserPath(folderName, provider);
|
|
8019
|
+
const result = await cloudCreateFolder(provider, remotePath);
|
|
8020
|
+
return `Папка создана или уже была на облачном диске: ${result.path}`;
|
|
8021
|
+
}
|
|
8022
|
+
|
|
8023
|
+
if (/(покажи|список|что.+лежит|файлы|папки)/iu.test(normalized)) {
|
|
8024
|
+
const remotePath = extractCloudPath(question) || cloudRootForProvider(provider);
|
|
8025
|
+
const rows = await cloudList(provider, normalizeCloudUserPath(remotePath, provider));
|
|
8026
|
+
if (rows.length === 0) return `В папке ${normalizeCloudUserPath(remotePath, provider)} нет данных.`;
|
|
8027
|
+
return [
|
|
8028
|
+
`Облачный диск ${provider}, папка ${normalizeCloudUserPath(remotePath, provider)}:`,
|
|
8029
|
+
...rows.slice(0, 20).map((row, index) => `${index + 1}. ${row.type === "dir" ? "папка" : "файл"} ${row.name} — ${row.path}`),
|
|
8030
|
+
].join("\n");
|
|
8031
|
+
}
|
|
8032
|
+
|
|
8033
|
+
if (/(найди|поиск|где лежит)/iu.test(normalized)) {
|
|
8034
|
+
const query = cleanupCloudQuery(question);
|
|
8035
|
+
const rows = await cloudFind(provider, query, { path: cloudRootForProvider(provider), limit: 10 });
|
|
8036
|
+
if (rows.length === 0) return `На облачном диске не нашел: ${query}`;
|
|
8037
|
+
return [
|
|
8038
|
+
`Нашел на облачном диске ${provider}:`,
|
|
8039
|
+
...rows.map((row, index) => `${index + 1}. ${row.name} — ${row.path}`),
|
|
8040
|
+
].join("\n");
|
|
8041
|
+
}
|
|
8042
|
+
|
|
8043
|
+
if (/(ссылк|поделись|опубликуй)/iu.test(normalized)) {
|
|
8044
|
+
const remotePath = extractCloudPath(question);
|
|
8045
|
+
if (!remotePath) return "Укажите путь к файлу на облачном диске, например: /IOLA/reports/report.md";
|
|
8046
|
+
const result = await cloudShare(provider, normalizeCloudUserPath(remotePath, provider));
|
|
8047
|
+
return `Публичная ссылка: ${result.publicUrl}`;
|
|
8048
|
+
}
|
|
8049
|
+
|
|
8050
|
+
if (/(сохрани|запиши).{0,40}(на яндекс диске|в облак|на диск)/iu.test(normalized)) {
|
|
8051
|
+
const text = cleanupCloudSaveText(question);
|
|
8052
|
+
if (!text) return "Что сохранить на облачный диск?";
|
|
8053
|
+
const remotePath = `${cloudRootForProvider(provider)}/notes/iola-${timestampForFile()}.txt`;
|
|
8054
|
+
const tempPath = path.join(CONFIG_DIR, `cloud-save-${Date.now()}.txt`);
|
|
8055
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
8056
|
+
await writeFile(tempPath, text, "utf8");
|
|
8057
|
+
try {
|
|
8058
|
+
await cloudUpload(provider, tempPath, remotePath, { overwrite: true });
|
|
8059
|
+
} finally {
|
|
8060
|
+
await rm(tempPath, { force: true }).catch(() => {});
|
|
8061
|
+
}
|
|
8062
|
+
return `Сохранил текст на облачный диск: ${remotePath}`;
|
|
8063
|
+
}
|
|
8064
|
+
} catch (error) {
|
|
8065
|
+
return `Не смог выполнить облачный запрос: ${error instanceof Error ? error.message : String(error)}`;
|
|
8066
|
+
}
|
|
8067
|
+
return "";
|
|
8068
|
+
}
|
|
8069
|
+
|
|
8070
|
+
function isCloudQuestion(question) {
|
|
8071
|
+
return /(яндекс.?диск|yandex.?disk|облак|облачн|на диск|с диска|в диск|cloud|mail\.?ru|публичн.*ссылк|поделиться.*файл)/iu.test(String(question || ""));
|
|
8072
|
+
}
|
|
8073
|
+
|
|
8074
|
+
function normalizeCloudUserPath(value, provider = "yandex-disk") {
|
|
8075
|
+
const root = cloudRootForProvider(provider);
|
|
8076
|
+
let text = String(value || "").trim().replace(/\\/g, "/");
|
|
8077
|
+
text = text.replace(/^["'«»]+|["'«»]+$/gu, "").trim();
|
|
8078
|
+
if (!text) return root;
|
|
8079
|
+
if (text.startsWith("/")) return text;
|
|
8080
|
+
if (normalizeGeoText(text).startsWith(normalizeGeoText(root).replace(/^\//u, ""))) return `/${text.replace(/^\/+/u, "")}`;
|
|
8081
|
+
return `${root.replace(/\/+$/u, "")}/${text.replace(/^\/+/u, "")}`;
|
|
8082
|
+
}
|
|
8083
|
+
|
|
8084
|
+
function extractCloudFolderName(question) {
|
|
8085
|
+
const text = String(question || "").trim();
|
|
8086
|
+
const match = text.match(/(?:папк[ауи]?|директор(?:ию|ия|ии)?)\s+["'«]?([^"'».,!?]+)["'»]?/iu)
|
|
8087
|
+
|| text.match(/(?:названи(?:ем|е)|имя)\s+["'«]?([^"'».,!?]+)["'»]?/iu);
|
|
8088
|
+
if (!match?.[1]) return "";
|
|
8089
|
+
return cleanupCloudObjectName(match[1]);
|
|
8090
|
+
}
|
|
8091
|
+
|
|
8092
|
+
function extractCloudPath(question) {
|
|
8093
|
+
const text = String(question || "").trim();
|
|
8094
|
+
const pathMatch = text.match(/(?:^|\s)(\/IOLA\/[^\s]+|\/[^\s]+)/iu);
|
|
8095
|
+
if (pathMatch?.[1]) return pathMatch[1];
|
|
8096
|
+
const quoted = text.match(/["«]([^"»]+)["»]/u);
|
|
8097
|
+
if (quoted?.[1]) return quoted[1];
|
|
8098
|
+
const afterFolder = text.match(/(?:папк[аеуы]?|файл[ае]?)\s+([^,.!?]+)/iu);
|
|
8099
|
+
return afterFolder?.[1] ? cleanupCloudObjectName(afterFolder[1]) : "";
|
|
8100
|
+
}
|
|
8101
|
+
|
|
8102
|
+
function cleanupCloudObjectName(value) {
|
|
8103
|
+
return String(value || "")
|
|
8104
|
+
.replace(/\b(?:на|в|у меня|яндекс.?диск(?:е)?|диск(?:е)?|облак(?:е|о)?|создай|сделай|добавь|покажи)\b/giu, " ")
|
|
8105
|
+
.replace(/\s+/g, " ")
|
|
8106
|
+
.trim();
|
|
8107
|
+
}
|
|
8108
|
+
|
|
8109
|
+
function cleanupCloudQuery(question) {
|
|
8110
|
+
return String(question || "")
|
|
8111
|
+
.replace(/\b(?:найди|поиск|где лежит|на|в|яндекс.?диск(?:е)?|облак(?:е|о)?|диск(?:е)?|файл|документ)\b/giu, " ")
|
|
8112
|
+
.replace(/[?.!]+$/u, "")
|
|
8113
|
+
.replace(/\s+/g, " ")
|
|
8114
|
+
.trim();
|
|
8115
|
+
}
|
|
8116
|
+
|
|
8117
|
+
function cleanupCloudSaveText(question) {
|
|
8118
|
+
return String(question || "")
|
|
8119
|
+
.replace(/^.*?(?:сохрани|запиши)\s+/iu, "")
|
|
8120
|
+
.replace(/\s+(?:на яндекс диске|в облак[ео]|на диск).*$/iu, "")
|
|
8121
|
+
.trim();
|
|
8122
|
+
}
|
|
8123
|
+
|
|
7964
8124
|
function detectDirectDataFields(normalizedQuestion) {
|
|
7965
8125
|
const fields = [];
|
|
7966
8126
|
if (/(директ|руководител|заведующ|кто возглавляет)/iu.test(normalizedQuestion)) fields.push("head");
|
|
@@ -8244,6 +8404,11 @@ async function localToolAsk(question, providerConfig, options) {
|
|
|
8244
8404
|
if (!options.quiet) console.log(casualAnswer);
|
|
8245
8405
|
return casualAnswer;
|
|
8246
8406
|
}
|
|
8407
|
+
const cloudAnswer = await buildCloudDirectAnswer(question);
|
|
8408
|
+
if (cloudAnswer) {
|
|
8409
|
+
if (!options.quiet) console.log(cloudAnswer);
|
|
8410
|
+
return cloudAnswer;
|
|
8411
|
+
}
|
|
8247
8412
|
const geoAnswer = await buildGeoDirectAnswer(question);
|
|
8248
8413
|
if (geoAnswer) {
|
|
8249
8414
|
if (!options.quiet) console.log(geoAnswer);
|
|
@@ -10797,8 +10962,10 @@ function selectSkillsForPrompt(config, question = "", options = {}) {
|
|
|
10797
10962
|
if (enabled.has("local-model")) selected.add("local-model");
|
|
10798
10963
|
if (enabled.has("open-data") && shouldUseDataContext(question, options)) selected.add("open-data");
|
|
10799
10964
|
if (enabled.has("geo") && isGeoQuestion(normalized)) selected.add("geo");
|
|
10965
|
+
const cloudQuestion = isCloudQuestion(normalized);
|
|
10966
|
+
if (enabled.has("personal-docs") && cloudQuestion) selected.add("personal-docs");
|
|
10800
10967
|
if (enabled.has("reports") && /(отчет|отчёт|выгруз|csv|xlsx|качество|провер)/iu.test(normalized)) selected.add("reports");
|
|
10801
|
-
if (enabled.has("local-files") && (options.files || /(файл|папк|readme|документ|архив)/iu.test(normalized))) selected.add("local-files");
|
|
10968
|
+
if (enabled.has("local-files") && !cloudQuestion && (options.files || /(файл|папк|readme|документ|архив)/iu.test(normalized))) selected.add("local-files");
|
|
10802
10969
|
if (enabled.has("browser-agent") && /(браузер|сайт|страниц|url|https?:\/\/)/iu.test(normalized)) selected.add("browser-agent");
|
|
10803
10970
|
return selected;
|
|
10804
10971
|
}
|
|
@@ -50,6 +50,7 @@ iola cloud status
|
|
|
50
50
|
iola cloud doctor
|
|
51
51
|
iola cloud use yandex-disk
|
|
52
52
|
iola cloud ls /IOLA
|
|
53
|
+
iola cloud mkdir /IOLA/Фото
|
|
53
54
|
iola cloud find "справка" --path /IOLA
|
|
54
55
|
iola cloud upload report.md /IOLA/reports/report.md
|
|
55
56
|
iola cloud download /IOLA/reports/report.md ./report.md
|
|
@@ -18,6 +18,7 @@ iola cloud status
|
|
|
18
18
|
iola cloud doctor
|
|
19
19
|
iola cloud use yandex-disk
|
|
20
20
|
iola cloud ls /IOLA
|
|
21
|
+
iola cloud mkdir /IOLA/Фото
|
|
21
22
|
iola cloud find "справка" --path /IOLA
|
|
22
23
|
iola cloud upload report.md /IOLA/reports/report.md
|
|
23
24
|
iola cloud download /IOLA/reports/report.md ./report.md
|
|
@@ -36,20 +37,60 @@ iola cloud backup
|
|
|
36
37
|
- получение OAuth-токена: `https://yandex.ru/dev/id/doc/ru/access`
|
|
37
38
|
- получение токена вручную для проверки: `https://yandex.ru/dev/id/doc/ru/tokens/debug-token`
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
### Получение OAuth-токена Яндекс Диска
|
|
40
41
|
|
|
41
42
|
1. Откройте страницу Яндекс OAuth: `https://oauth.yandex.ru/`.
|
|
42
|
-
2.
|
|
43
|
-
3.
|
|
44
|
-
4.
|
|
45
|
-
5.
|
|
43
|
+
2. Если Яндекс просит пройти верификацию через Госуслуги, пройдите ее. Без этого создание OAuth-приложения может быть недоступно.
|
|
44
|
+
3. Нажмите `Создать`.
|
|
45
|
+
4. В окне `Какое приложение хотите создать?` выберите `Для авторизации пользователей`.
|
|
46
|
+
5. Нажмите `Перейти к созданию`.
|
|
47
|
+
6. На шаге `Создание приложения` заполните:
|
|
48
|
+
- `Название вашего сервиса`: например `iola-cli`;
|
|
49
|
+
- `Иконка сервиса`: загрузите PNG-иконку до 1 МБ. Готовая иконка iola-cli доступна по ссылке: `https://raw.githubusercontent.com/adm-iola/iola-cli/main/docs/assets/iola-oauth-icon.png`;
|
|
50
|
+
- `Почта для связи`: оставьте свою почту или укажите актуальную.
|
|
51
|
+
7. Нажмите `Продолжить`.
|
|
52
|
+
8. На шаге `Платформы приложений` выберите `Веб-сервисы`.
|
|
53
|
+
9. В поле `Redirect URI` укажите:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
https://oauth.yandex.ru/verification_code
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
10. Нажмите кнопку добавления рядом с `Redirect URI`, если интерфейс показывает такую кнопку.
|
|
60
|
+
11. В поле `Suggest Hostname`, если оно обязательно, укажите сайт проекта или любой понятный URL сервиса, например:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
https://github.com
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
12. Нажмите `Продолжить`.
|
|
67
|
+
13. На шаге `Права доступа к данным пользователей` не выбирайте лишние основные права: телефон, почта, дата рождения, профиль не нужны.
|
|
68
|
+
14. В блоке `Дополнительные` через поле `Название доступа` добавьте три права:
|
|
69
|
+
- `Чтение всего Диска` / `cloud_api:disk.read`;
|
|
70
|
+
- `Запись в любом месте на Диске` / `cloud_api:disk.write`;
|
|
71
|
+
- `Доступ к информации о Диске` / `cloud_api:disk.info`.
|
|
72
|
+
15. Нажмите `Продолжить`.
|
|
73
|
+
16. На финальном экране проверьте, что приложение запрашивает только три права Диска.
|
|
74
|
+
17. Нажмите `Всё верно, создать приложение`.
|
|
75
|
+
18. На странице созданного приложения скопируйте `ClientID`.
|
|
76
|
+
19. Откройте ссылку, заменив `CLIENT_ID` на ваш `ClientID`:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
https://oauth.yandex.ru/authorize?response_type=token&client_id=CLIENT_ID
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
20. На экране авторизации нажмите `Войти как ...`.
|
|
83
|
+
21. Если Яндекс показывает предупреждение `Сервис ещё не верифицирован`, это нормально для личного приложения. Продолжайте только если приложение создавали вы сами и доверяете ему.
|
|
84
|
+
22. Яндекс перенаправит на страницу `verification_code`, где будет показан OAuth-токен. В адресной строке он также находится после `access_token=`.
|
|
85
|
+
23. Скопируйте OAuth-токен.
|
|
86
|
+
24. В CLI выполните:
|
|
46
87
|
|
|
47
88
|
```bash
|
|
48
89
|
iola cloud setup yandex-disk
|
|
49
90
|
```
|
|
50
91
|
|
|
51
|
-
|
|
52
|
-
|
|
92
|
+
25. Вставьте OAuth-токен.
|
|
93
|
+
26. Проверьте подключение:
|
|
53
94
|
|
|
54
95
|
```bash
|
|
55
96
|
iola cloud doctor
|
|
@@ -57,6 +98,20 @@ iola cloud doctor
|
|
|
57
98
|
|
|
58
99
|
Секрет сохраняется локально в `~/.iola/secrets.json`.
|
|
59
100
|
|
|
101
|
+
После успешной проверки CLI создаст или использует папку `/IOLA` на Яндекс Диске.
|
|
102
|
+
|
|
103
|
+
Обычно такой токен выдается на длительный срок. Если доступ перестал работать, получите новый токен через ту же ссылку авторизации и повторите `iola cloud setup yandex-disk`.
|
|
104
|
+
|
|
105
|
+
После подключения можно работать с облаком обычными фразами в CLI:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
создай у меня на яндекс диске папку фото
|
|
109
|
+
покажи что лежит на яндекс диске
|
|
110
|
+
найди на яндекс диске справку
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Такие запросы обрабатывает skill `personal-docs`. Они не требуют включать локальный режим `iola files mode`, потому что это не работа с файлами на ПК.
|
|
114
|
+
|
|
60
115
|
## Облако Mail.ru
|
|
61
116
|
|
|
62
117
|
Облако Mail.ru подключается через WebDAV.
|
|
@@ -114,6 +114,15 @@ iola geo services "Йошкар-Ола, улица Петрова, 15"
|
|
|
114
114
|
|
|
115
115
|
Сохранить ответ CLI, отчет, карточку учреждения или список ближайших объектов в `/IOLA`.
|
|
116
116
|
|
|
117
|
+
### cloud-create-folder
|
|
118
|
+
|
|
119
|
+
Создать папку на подключенном облачном диске.
|
|
120
|
+
|
|
121
|
+
Пример:
|
|
122
|
+
|
|
123
|
+
- `создай у меня на яндекс диске папку фото`;
|
|
124
|
+
- `создай папку документы в облаке`.
|
|
125
|
+
|
|
117
126
|
### cloud-share-link
|
|
118
127
|
|
|
119
128
|
Создать публичную ссылку на файл. В первом контуре поддерживается для Яндекс Диска.
|