@iola_adm/iola-cli 0.1.60 → 0.1.61
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 -0
- package/package.json +1 -1
- package/src/cli.js +101 -3
- package/wiki/Daemon-RPC-/320/270-cron.md +6 -0
- package/wiki//320/232/320/276/320/274/320/260/320/275/320/264/321/213.md +3 -0
- package/wiki//320/237/320/276/320/264/320/272/320/273/321/216/321/207/320/265/320/275/320/270/320/265-/320/223/320/276/321/201/321/203/321/201/320/273/321/203/320/263.md +26 -0
package/README.md
CHANGED
|
@@ -89,6 +89,7 @@ iola gosuslugi connect
|
|
|
89
89
|
iola gosuslugi whoami
|
|
90
90
|
iola gosuslugi debt
|
|
91
91
|
iola gosuslugi notifications --unread
|
|
92
|
+
iola gosuslugi keepalive
|
|
92
93
|
```
|
|
93
94
|
|
|
94
95
|
Локальная модель через Ollama:
|
|
@@ -138,6 +139,7 @@ iola version --check
|
|
|
138
139
|
- браузерный runtime через Playwright: чтение страниц, скриншоты, PDF, клики, ввод и eval;
|
|
139
140
|
- личное локальное подключение Госуслуг через отдельный браузерный профиль на ПК пользователя;
|
|
140
141
|
- read-only tools Госуслуг для агента: ФИО, дата рождения, задолженности и уведомления;
|
|
142
|
+
- keepalive-проверка сессии Госуслуг каждые 30 минут без обхода 2FA;
|
|
141
143
|
- управляемые локальные файловые операции с режимами `locked`, `read-only`, `workspace-write`, `full-access`;
|
|
142
144
|
- планы выполнения, traces, tasks, artifacts, snapshots и policy-профили;
|
|
143
145
|
- экспорт отчетов в Excel/Word-совместимые файлы;
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -290,6 +290,7 @@ const SLASH_COMMANDS = [
|
|
|
290
290
|
{ command: "/gosuslugi connect", description: "открыть личный вход Госуслуг" },
|
|
291
291
|
{ command: "/gosuslugi debt", description: "задолженности Госуслуг" },
|
|
292
292
|
{ command: "/gosuslugi notifications", description: "уведомления Госуслуг" },
|
|
293
|
+
{ command: "/gosuslugi keepalive", description: "проверка сессии каждые 30 минут" },
|
|
293
294
|
{ command: "/wiki", description: "ссылки на документацию" },
|
|
294
295
|
{ command: "/context list", description: "локальный контекст проекта" },
|
|
295
296
|
{ command: "/skills list", description: "skills" },
|
|
@@ -523,7 +524,7 @@ Usage:
|
|
|
523
524
|
iola fork SESSION_ID [TEXT]
|
|
524
525
|
iola features list|enable|disable
|
|
525
526
|
iola settings list|get|validate|doctor|init
|
|
526
|
-
iola gosuslugi terms|consent|status|connect|open|text|screenshot|whoami|debt|notifications|mark-read|logout|configure|login|userinfo
|
|
527
|
+
iola gosuslugi terms|consent|status|check|keepalive|install-keepalive|connect|open|text|screenshot|whoami|debt|notifications|mark-read|logout|configure|login|userinfo
|
|
527
528
|
iola wiki [open|links]
|
|
528
529
|
iola context list|show|init
|
|
529
530
|
iola skills list|show|paths|enable|disable|bundles|bundle|doctor
|
|
@@ -2025,6 +2026,25 @@ async function handleDb(args) {
|
|
|
2025
2026
|
return;
|
|
2026
2027
|
}
|
|
2027
2028
|
|
|
2029
|
+
if (action === "check") {
|
|
2030
|
+
const result = await gosuslugiCheck(options);
|
|
2031
|
+
if (options.json) printJson(result);
|
|
2032
|
+
else printKeyValue(result);
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
if (action === "keepalive") {
|
|
2037
|
+
await gosuslugiKeepalive(options);
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
if (action === "install-keepalive") {
|
|
2042
|
+
const id = addCronJob("каждые 30 минут", "gosuslugi check --silent");
|
|
2043
|
+
console.log(`Keepalive-задача добавлена: ${id}`);
|
|
2044
|
+
console.log("Для выполнения запускайте периодически: iola cron tick");
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2028
2048
|
if (action === "reset") {
|
|
2029
2049
|
const shouldReset = await confirm("Удалить локальную SQLite-БД iola.db? [y/N] ");
|
|
2030
2050
|
if (!shouldReset) {
|
|
@@ -2286,6 +2306,25 @@ async function handleGosuslugi(args) {
|
|
|
2286
2306
|
return;
|
|
2287
2307
|
}
|
|
2288
2308
|
|
|
2309
|
+
if (action === "check") {
|
|
2310
|
+
const result = await gosuslugiCheck(options);
|
|
2311
|
+
if (options.json) printJson(result);
|
|
2312
|
+
else printKeyValue(result);
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2316
|
+
if (action === "keepalive") {
|
|
2317
|
+
await gosuslugiKeepalive(options);
|
|
2318
|
+
return;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
if (action === "install-keepalive") {
|
|
2322
|
+
const id = addCronJob("каждые 30 минут", "gosuslugi check --silent");
|
|
2323
|
+
console.log(`Keepalive-задача добавлена: ${id}`);
|
|
2324
|
+
console.log("Для выполнения запускайте периодически: iola cron tick");
|
|
2325
|
+
return;
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2289
2328
|
if (action === "connect") {
|
|
2290
2329
|
await gosuslugiBrowserConnect(options);
|
|
2291
2330
|
return;
|
|
@@ -2389,7 +2428,7 @@ async function handleGosuslugi(args) {
|
|
|
2389
2428
|
return;
|
|
2390
2429
|
}
|
|
2391
2430
|
|
|
2392
|
-
throw new Error("Команды gosuslugi: terms, consent, status, connect, open, text, screenshot, whoami, debt, notifications, mark-read, logout, configure, login, userinfo.");
|
|
2431
|
+
throw new Error("Команды gosuslugi: terms, consent, status, check, keepalive, install-keepalive, connect, open, text, screenshot, whoami, debt, notifications, mark-read, logout, configure, login, userinfo.");
|
|
2393
2432
|
}
|
|
2394
2433
|
|
|
2395
2434
|
function targetOrDefault(args, options = {}) {
|
|
@@ -5775,6 +5814,10 @@ function isCronDue(job) {
|
|
|
5775
5814
|
if (normalized.includes("каждый час") || normalized.includes("hourly")) {
|
|
5776
5815
|
return !lastRun || now.getTime() - lastRun.getTime() >= 60 * 60 * 1000;
|
|
5777
5816
|
}
|
|
5817
|
+
const everyMinutes = normalized.match(/кажд(?:ые|ую)\s+(\d+)\s*(?:мин|минут)/u) || normalized.match(/every\s+(\d+)\s*(?:m|min|minutes)/u);
|
|
5818
|
+
if (everyMinutes) {
|
|
5819
|
+
return !lastRun || now.getTime() - lastRun.getTime() >= Number(everyMinutes[1]) * 60 * 1000;
|
|
5820
|
+
}
|
|
5778
5821
|
if (normalized.includes("каждый день") || normalized.includes("daily")) {
|
|
5779
5822
|
return !lastRun || now.toISOString().slice(0, 10) !== lastRun.toISOString().slice(0, 10);
|
|
5780
5823
|
}
|
|
@@ -7150,7 +7193,7 @@ function parseOptions(args) {
|
|
|
7150
7193
|
|
|
7151
7194
|
for (let index = 0; index < args.length; index += 1) {
|
|
7152
7195
|
const arg = args[index];
|
|
7153
|
-
if (arg === "--json" || arg === "--yes" || arg === "--silent" || arg === "--events" || arg === "--stream-json" || arg === "--stdio" || arg === "--system" || arg === "--headed" || arg === "--headless" || arg === "--no-history" || arg === "--summary" || arg === "--all" || arg === "--full" || arg === "--unread" || arg === "--local" || arg === "--cache" || arg === "--tools" || arg === "--files" || arg === "--plan" || arg === "--trace" || arg === "--diff" || arg === "--stage" || arg === "--fts" || arg === "--bare" || arg === "--quiet" || arg === "--no-color" || arg === "--fail-on-empty" || arg === "--debug" || arg === "--fix" || arg === "--append") {
|
|
7196
|
+
if (arg === "--json" || arg === "--yes" || arg === "--silent" || arg === "--events" || arg === "--stream-json" || arg === "--stdio" || arg === "--system" || arg === "--headed" || arg === "--headless" || arg === "--no-history" || arg === "--summary" || arg === "--all" || arg === "--full" || arg === "--unread" || arg === "--once" || arg === "--local" || arg === "--cache" || arg === "--tools" || arg === "--files" || arg === "--plan" || arg === "--trace" || arg === "--diff" || arg === "--stage" || arg === "--fts" || arg === "--bare" || arg === "--quiet" || arg === "--no-color" || arg === "--fail-on-empty" || arg === "--debug" || arg === "--fix" || arg === "--append") {
|
|
7154
7197
|
result[arg.slice(2)] = true;
|
|
7155
7198
|
} else if (arg === "--check" || arg === "--upgrade-node") {
|
|
7156
7199
|
result.check = true;
|
|
@@ -7799,6 +7842,61 @@ async function gosuslugiMarkNotificationsRead(options = {}) {
|
|
|
7799
7842
|
console.log("Команда отметки прочитанным выполнена. Проверьте статус: iola gosuslugi notifications --unread");
|
|
7800
7843
|
}
|
|
7801
7844
|
|
|
7845
|
+
async function gosuslugiCheck(options = {}) {
|
|
7846
|
+
try {
|
|
7847
|
+
const result = await gosuslugiWhoami({ wait: options.wait || 2000 });
|
|
7848
|
+
return {
|
|
7849
|
+
status: "ok",
|
|
7850
|
+
authorized: "yes",
|
|
7851
|
+
fio: result.summary.fio,
|
|
7852
|
+
checkedAt: new Date().toISOString(),
|
|
7853
|
+
nextAction: "-",
|
|
7854
|
+
};
|
|
7855
|
+
} catch (error) {
|
|
7856
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7857
|
+
const result = {
|
|
7858
|
+
status: "needs-login",
|
|
7859
|
+
authorized: "unknown",
|
|
7860
|
+
checkedAt: new Date().toISOString(),
|
|
7861
|
+
nextAction: "iola gosuslugi connect",
|
|
7862
|
+
error: message,
|
|
7863
|
+
};
|
|
7864
|
+
if (!options.silent) {
|
|
7865
|
+
console.error("Сессия Госуслуг недоступна или требует повторный вход.");
|
|
7866
|
+
console.error("Запустите: iola gosuslugi connect");
|
|
7867
|
+
}
|
|
7868
|
+
return result;
|
|
7869
|
+
}
|
|
7870
|
+
}
|
|
7871
|
+
|
|
7872
|
+
async function gosuslugiKeepalive(options = {}) {
|
|
7873
|
+
const intervalMs = parseDurationMs(options.interval || "30m");
|
|
7874
|
+
const once = Boolean(options.once);
|
|
7875
|
+
console.log(`Gosuslugi keepalive запущен. Интервал: ${Math.round(intervalMs / 60000)} мин.`);
|
|
7876
|
+
console.log("Остановить: Ctrl+C");
|
|
7877
|
+
while (true) {
|
|
7878
|
+
const result = await gosuslugiCheck({ silent: true });
|
|
7879
|
+
const line = result.status === "ok"
|
|
7880
|
+
? `[${result.checkedAt}] Госуслуги: сессия активна (${result.fio || "-"})`
|
|
7881
|
+
: `[${result.checkedAt}] Госуслуги: нужен повторный вход. Запустите: iola gosuslugi connect`;
|
|
7882
|
+
console.log(line);
|
|
7883
|
+
if (once) return;
|
|
7884
|
+
await sleep(intervalMs);
|
|
7885
|
+
}
|
|
7886
|
+
}
|
|
7887
|
+
|
|
7888
|
+
function parseDurationMs(value) {
|
|
7889
|
+
const text = String(value || "30m").trim().toLocaleLowerCase("ru-RU");
|
|
7890
|
+
const match = text.match(/^(\d+(?:[.,]\d+)?)(ms|s|m|h|мин|минут|час|часа|часов)?$/u);
|
|
7891
|
+
if (!match) throw new Error("Интервал задается как 30m, 1800s или 1h.");
|
|
7892
|
+
const amount = Number(match[1].replace(",", "."));
|
|
7893
|
+
const unit = match[2] || "m";
|
|
7894
|
+
if (unit === "ms") return Math.max(1000, amount);
|
|
7895
|
+
if (unit === "s") return Math.max(1000, amount * 1000);
|
|
7896
|
+
if (unit === "h" || unit.startsWith("час")) return Math.max(1000, amount * 60 * 60 * 1000);
|
|
7897
|
+
return Math.max(1000, amount * 60 * 1000);
|
|
7898
|
+
}
|
|
7899
|
+
|
|
7802
7900
|
function printGosuslugiDebt(result) {
|
|
7803
7901
|
printKeyValue({
|
|
7804
7902
|
total: result.total,
|
|
@@ -34,3 +34,9 @@ iola cron delete 1
|
|
|
34
34
|
|
|
35
35
|
`cron tick` проверяет задачи, которые пора выполнить. Его можно запускать вручную, через Windows Task Scheduler или другой планировщик.
|
|
36
36
|
|
|
37
|
+
Пример проверки сессии Госуслуг каждые 30 минут:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
iola gosuslugi install-keepalive
|
|
41
|
+
iola cron tick
|
|
42
|
+
```
|
|
@@ -95,6 +95,9 @@ iola context list
|
|
|
95
95
|
iola settings list
|
|
96
96
|
iola settings validate
|
|
97
97
|
iola gosuslugi status
|
|
98
|
+
iola gosuslugi check
|
|
99
|
+
iola gosuslugi keepalive
|
|
100
|
+
iola gosuslugi install-keepalive
|
|
98
101
|
iola gosuslugi terms
|
|
99
102
|
iola gosuslugi consent
|
|
100
103
|
iola gosuslugi connect
|
|
@@ -78,10 +78,36 @@ AI-агент может использовать read-only tools Госуслу
|
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
80
|
iola gosuslugi status
|
|
81
|
+
iola gosuslugi check
|
|
81
82
|
```
|
|
82
83
|
|
|
83
84
|
Команда показывает, принято ли согласие, где лежит локальный профиль и когда он был создан.
|
|
84
85
|
|
|
86
|
+
## Keepalive
|
|
87
|
+
|
|
88
|
+
Сессию Госуслуг нельзя сделать вечной: портал сам управляет сроком жизни входа и может попросить повторную двухфакторную аутентификацию. CLI может только мягко проверять сохраненный профиль.
|
|
89
|
+
|
|
90
|
+
Запуск проверки каждые 30 минут:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
iola gosuslugi keepalive
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Однократная проверка:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
iola gosuslugi keepalive --once
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Добавить локальную cron-задачу CLI:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
iola gosuslugi install-keepalive
|
|
106
|
+
iola cron tick
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`cron tick` нужно запускать системным планировщиком или вручную. Если сессия протухла, CLI попросит выполнить `iola gosuslugi connect`.
|
|
110
|
+
|
|
85
111
|
## Отключение
|
|
86
112
|
|
|
87
113
|
Удалить локальное подключение:
|