@pachca/cli 2026.8.1 → 2026.8.2
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/CHANGELOG.md +9 -1
- package/README.md +2 -0
- package/dist/client.js +13 -3
- package/dist/commands/bots/list-company.js +98 -0
- package/dist/commands/chats/list-company.js +99 -0
- package/dist/commands/chats/list.js +1 -1
- package/dist/commands/security/list.js +1 -1
- package/dist/commands/tasks/list.js +24 -1
- package/dist/data/alternatives.json +2 -0
- package/dist/data/changelog.json +31 -1
- package/dist/data/endpoints.json +1 -1
- package/dist/data/workflows.json +46 -3
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 2026.8.
|
|
3
|
+
## 2026.8.2 (12 августа 2026)
|
|
4
|
+
|
|
5
|
+
- **Добавлено** (chats list-company): Новая команда — все беседы и каналы пространства, включая закрытые, где вы не состоите. Флаг `--activity` со значением `active` или `archived` оставляет одно состояние, по умолчанию отдаются оба. Нужна роль владельца пространства, тариф «Корпорация» и право `company_chats:read`
|
|
6
|
+
- **Добавлено** (bots list-company): Новая команда — все боты пространства, включая недоступные вам для редактирования. У таких ботов заполнены только имя и никнейм, остальные настройки приходят пустыми. Фильтр по имени — флаг `--query`. Нужна роль владельца пространства, тариф «Корпорация» и право `company_bots:read`
|
|
7
|
+
- **Добавлено** (tasks list): Флаги `--status`, `--chat-ids`, `--performer-ids` и `--author-id` для фильтрации напоминаний. С `--chat-ids` выдача расширяется до всех напоминаний указанных чатов, а не только ваших
|
|
8
|
+
- **Добавлено** (security list): Фильтр `--event-key` принимает `company_chats_accessed` и `company_bots_accessed`
|
|
9
|
+
- **Исправлено**: Недостающий скоуп в ошибке `insufficient_scope` берётся из заголовка `WWW-Authenticate` — раньше его вытаскивали регуляркой из текста сообщения, и он терялся при любой смене формулировки. Разбор текста остался запасным путём
|
|
10
|
+
|
|
11
|
+
## 2026.8.1 (7 августа 2026)
|
|
4
12
|
|
|
5
13
|
- **Добавлено** (auth login): Вход через браузер — без ручной вставки токена. CLI показывает адрес и код, открывает браузер и ждёт подтверждения. Токен такого входа живёт час и продлевается сам перед каждой командой; при параллельных процессах обновляет только один, остальные ждут результат. Флаг `--no-browser` печатает адрес и код, не открывая браузер. `--token` и `PACHCA_TOKEN` работают как раньше — это путь для CI и агентов
|
|
6
14
|
- **Добавлено** (auth login): Токен хранится в хранилище ключей ОС — Keychain на macOS, Secret Service на Linux, Диспетчер учётных данных на Windows; в файле конфигурации остаются только имя, почта и права. Где хранилища нет (headless-машина, контейнер), CLI сохраняет токен в файл и сообщает об этом при входе. Отказаться от хранилища: флаг `--insecure-storage` или переменная `PACHCA_SECRET_STORE=file`
|
package/README.md
CHANGED
|
@@ -86,6 +86,7 @@ pachca guide # список всех сценариев
|
|
|
86
86
|
| `pachca bots update` | Редактирование бота |
|
|
87
87
|
| `pachca bots delete` | Удаление бота |
|
|
88
88
|
| `pachca bots recreate-token` | Ротация токена бота |
|
|
89
|
+
| `pachca bots list-company` | Список ботов пространства |
|
|
89
90
|
| `pachca bots list-events` | История событий |
|
|
90
91
|
| `pachca bots remove-event` | Удаление события |
|
|
91
92
|
|
|
@@ -101,6 +102,7 @@ pachca guide # список всех сценариев
|
|
|
101
102
|
| `pachca chats update` | Редактирование чата |
|
|
102
103
|
| `pachca chats archive` | Архивация чата |
|
|
103
104
|
| `pachca chats unarchive` | Разархивация чата |
|
|
105
|
+
| `pachca chats list-company` | Список чатов пространства |
|
|
104
106
|
|
|
105
107
|
### members
|
|
106
108
|
|
package/dist/client.js
CHANGED
|
@@ -195,7 +195,8 @@ export async function request(opts, clientFlags) {
|
|
|
195
195
|
if (!response.ok) {
|
|
196
196
|
s?.stop('');
|
|
197
197
|
const requestId = response.headers.get('x-request-id') || undefined;
|
|
198
|
-
|
|
198
|
+
const authenticate = response.headers.get('www-authenticate') || undefined;
|
|
199
|
+
throw createApiError(response.status, data, requestId, authenticate);
|
|
199
200
|
}
|
|
200
201
|
s?.stop('');
|
|
201
202
|
return { data, status: response.status, headers: response.headers };
|
|
@@ -228,12 +229,21 @@ export async function request(opts, clientFlags) {
|
|
|
228
229
|
message: lastError?.message || 'Failed to connect to server',
|
|
229
230
|
});
|
|
230
231
|
}
|
|
231
|
-
|
|
232
|
+
// Недостающий скоуп по RFC 6750 приходит в параметре scope заголовка
|
|
233
|
+
// WWW-Authenticate: Bearer error="insufficient_scope", …, scope="profile:read"
|
|
234
|
+
function scopeFromChallenge(header) {
|
|
235
|
+
if (!header)
|
|
236
|
+
return undefined;
|
|
237
|
+
return /(?:^|[\s,])scope="([^"]*)"/.exec(header)?.[1] || undefined;
|
|
238
|
+
}
|
|
239
|
+
function createApiError(status, body, requestId, authenticate) {
|
|
232
240
|
// Scope refusal is a distinct case from "token is bad": the token works, it
|
|
233
241
|
// just may not do this. Pull the missing scope out so the command can name it.
|
|
234
242
|
if (isRecord(body) && body.error === 'insufficient_scope') {
|
|
235
243
|
const description = typeof body.error_description === 'string' ? body.error_description : '';
|
|
236
|
-
|
|
244
|
+
// Заголовок — источник по умолчанию: там скоуп лежит отдельным параметром.
|
|
245
|
+
// Разбор error_description оставлен запасным путём для версий API без заголовка.
|
|
246
|
+
const scope = scopeFromChallenge(authenticate) || /Required:\s*([\w:]+)/.exec(description)?.[1];
|
|
237
247
|
return new ApiError({
|
|
238
248
|
error: description || 'Insufficient scope',
|
|
239
249
|
code: status,
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
export default class BotsListCompany extends BaseCommand {
|
|
5
|
+
static description = "Список ботов пространства";
|
|
6
|
+
static examples = [
|
|
7
|
+
"Инвентаризация всех ботов пространства — Получи всех ботов пространства, а не только доступных для редактирования:\n $ pachca bots list-company"
|
|
8
|
+
];
|
|
9
|
+
static scope = "company_bots:read";
|
|
10
|
+
static plan = "corporation";
|
|
11
|
+
static apiMethod = "GET";
|
|
12
|
+
static apiPath = "/company/bots";
|
|
13
|
+
static defaultColumns = ["id", "webhook"];
|
|
14
|
+
static args = {};
|
|
15
|
+
static flags = {
|
|
16
|
+
...BaseCommand.baseFlags,
|
|
17
|
+
'query': Flags.string({
|
|
18
|
+
description: "Поисковая фраза для фильтрации ботов по имени",
|
|
19
|
+
}),
|
|
20
|
+
limit: Flags.integer({
|
|
21
|
+
description: 'Количество результатов на страницу',
|
|
22
|
+
}),
|
|
23
|
+
cursor: Flags.string({
|
|
24
|
+
description: 'Курсор для следующей страницы',
|
|
25
|
+
}),
|
|
26
|
+
all: Flags.boolean({
|
|
27
|
+
description: 'Загрузить все страницы автоматически',
|
|
28
|
+
default: false,
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
async run() {
|
|
32
|
+
const { args, flags } = await this.parse(BotsListCompany);
|
|
33
|
+
this.parsedFlags = flags;
|
|
34
|
+
if (flags.all) {
|
|
35
|
+
// Auto-pagination
|
|
36
|
+
const allData = [];
|
|
37
|
+
let nextCursor = undefined;
|
|
38
|
+
let pages = 0;
|
|
39
|
+
const seenCursors = new Set();
|
|
40
|
+
while (pages < 500) {
|
|
41
|
+
const query = {
|
|
42
|
+
query: flags['query'],
|
|
43
|
+
limit: flags.limit,
|
|
44
|
+
cursor: nextCursor,
|
|
45
|
+
};
|
|
46
|
+
const response = await this.apiRequest({ method: 'GET', path: '/company/bots', query });
|
|
47
|
+
const body = response.data;
|
|
48
|
+
const items = body.data;
|
|
49
|
+
if (items)
|
|
50
|
+
allData.push(...items);
|
|
51
|
+
const meta = body.meta;
|
|
52
|
+
const paginate = meta?.paginate;
|
|
53
|
+
nextCursor = paginate?.next_page;
|
|
54
|
+
pages++;
|
|
55
|
+
// Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
|
|
56
|
+
const hasNext = paginate?.has_next;
|
|
57
|
+
if (typeof hasNext === 'boolean') {
|
|
58
|
+
if (!hasNext)
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
else if (!items || items.length === 0) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
if (process.stderr.isTTY) {
|
|
65
|
+
const total = paginate?.total;
|
|
66
|
+
const progress = total ? `${allData.length} / ${total}` : String(allData.length);
|
|
67
|
+
process.stderr.write(`\r Загружено: ${progress}...`);
|
|
68
|
+
}
|
|
69
|
+
if (!nextCursor)
|
|
70
|
+
break;
|
|
71
|
+
if (seenCursors.has(nextCursor)) {
|
|
72
|
+
process.stderr.write('\n⚠ Обнаружен цикл пагинации, остановка.\n');
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
seenCursors.add(nextCursor);
|
|
76
|
+
}
|
|
77
|
+
if (pages >= 500) {
|
|
78
|
+
process.stderr.write('\n⚠ Достигнут лимит 500 страниц.\n');
|
|
79
|
+
}
|
|
80
|
+
if (process.stderr.isTTY)
|
|
81
|
+
process.stderr.write('\n');
|
|
82
|
+
this.output(allData);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const { data } = await this.apiRequest({
|
|
86
|
+
method: 'GET',
|
|
87
|
+
path: '/company/bots',
|
|
88
|
+
query: {
|
|
89
|
+
query: flags['query'],
|
|
90
|
+
limit: flags.limit,
|
|
91
|
+
cursor: flags.cursor,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
const responseBody = (data ?? {});
|
|
95
|
+
const items = responseBody.data ?? responseBody;
|
|
96
|
+
this.output(items);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
export default class ChatsListCompany extends BaseCommand {
|
|
5
|
+
static description = "Список чатов пространства";
|
|
6
|
+
static examples = [
|
|
7
|
+
"Выгрузить все чаты пространства, включая закрытые — Получи беседы и каналы всего пространства, включая закрытые, где владелец токена не состоит:\n $ pachca chats list-company"
|
|
8
|
+
];
|
|
9
|
+
static scope = "company_chats:read";
|
|
10
|
+
static plan = "corporation";
|
|
11
|
+
static apiMethod = "GET";
|
|
12
|
+
static apiPath = "/company/chats";
|
|
13
|
+
static defaultColumns = ["id", "name", "created_at", "owner_id", "channel"];
|
|
14
|
+
static args = {};
|
|
15
|
+
static flags = {
|
|
16
|
+
...BaseCommand.baseFlags,
|
|
17
|
+
'activity': Flags.string({
|
|
18
|
+
description: "Состояние чатов. Если параметр не указан, возвращаются и активные, и архивные чаты.",
|
|
19
|
+
options: ["active", "archived"],
|
|
20
|
+
}),
|
|
21
|
+
limit: Flags.integer({
|
|
22
|
+
description: 'Количество результатов на страницу',
|
|
23
|
+
}),
|
|
24
|
+
cursor: Flags.string({
|
|
25
|
+
description: 'Курсор для следующей страницы',
|
|
26
|
+
}),
|
|
27
|
+
all: Flags.boolean({
|
|
28
|
+
description: 'Загрузить все страницы автоматически',
|
|
29
|
+
default: false,
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
async run() {
|
|
33
|
+
const { args, flags } = await this.parse(ChatsListCompany);
|
|
34
|
+
this.parsedFlags = flags;
|
|
35
|
+
if (flags.all) {
|
|
36
|
+
// Auto-pagination
|
|
37
|
+
const allData = [];
|
|
38
|
+
let nextCursor = undefined;
|
|
39
|
+
let pages = 0;
|
|
40
|
+
const seenCursors = new Set();
|
|
41
|
+
while (pages < 500) {
|
|
42
|
+
const query = {
|
|
43
|
+
activity: flags['activity'],
|
|
44
|
+
limit: flags.limit,
|
|
45
|
+
cursor: nextCursor,
|
|
46
|
+
};
|
|
47
|
+
const response = await this.apiRequest({ method: 'GET', path: '/company/chats', query });
|
|
48
|
+
const body = response.data;
|
|
49
|
+
const items = body.data;
|
|
50
|
+
if (items)
|
|
51
|
+
allData.push(...items);
|
|
52
|
+
const meta = body.meta;
|
|
53
|
+
const paginate = meta?.paginate;
|
|
54
|
+
nextCursor = paginate?.next_page;
|
|
55
|
+
pages++;
|
|
56
|
+
// Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
|
|
57
|
+
const hasNext = paginate?.has_next;
|
|
58
|
+
if (typeof hasNext === 'boolean') {
|
|
59
|
+
if (!hasNext)
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
else if (!items || items.length === 0) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (process.stderr.isTTY) {
|
|
66
|
+
const total = paginate?.total;
|
|
67
|
+
const progress = total ? `${allData.length} / ${total}` : String(allData.length);
|
|
68
|
+
process.stderr.write(`\r Загружено: ${progress}...`);
|
|
69
|
+
}
|
|
70
|
+
if (!nextCursor)
|
|
71
|
+
break;
|
|
72
|
+
if (seenCursors.has(nextCursor)) {
|
|
73
|
+
process.stderr.write('\n⚠ Обнаружен цикл пагинации, остановка.\n');
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
seenCursors.add(nextCursor);
|
|
77
|
+
}
|
|
78
|
+
if (pages >= 500) {
|
|
79
|
+
process.stderr.write('\n⚠ Достигнут лимит 500 страниц.\n');
|
|
80
|
+
}
|
|
81
|
+
if (process.stderr.isTTY)
|
|
82
|
+
process.stderr.write('\n');
|
|
83
|
+
this.output(allData);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const { data } = await this.apiRequest({
|
|
87
|
+
method: 'GET',
|
|
88
|
+
path: '/company/chats',
|
|
89
|
+
query: {
|
|
90
|
+
activity: flags['activity'],
|
|
91
|
+
limit: flags.limit,
|
|
92
|
+
cursor: flags.cursor,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
const responseBody = (data ?? {});
|
|
96
|
+
const items = responseBody.data ?? responseBody;
|
|
97
|
+
this.output(items);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -6,7 +6,7 @@ export default class ChatsList extends BaseCommand {
|
|
|
6
6
|
static examples = [
|
|
7
7
|
"Найти активные чаты за период — Получи чаты с активностью после указанной даты:\n $ pachca chats list",
|
|
8
8
|
"Найти и заархивировать неактивные чаты — Получи чаты без активности с нужной даты:\n $ pachca chats list",
|
|
9
|
-
"
|
|
9
|
+
"Выгрузить все чаты пространства, включая закрытые — Если метод ответил `403` — у токена нет скоупа `company_chats:read`, либо владелец токена не владелец пространства, либо у пространства нет тарифа «Корпорация». Тогда возьми открытые чаты обычным списком:\n $ pachca chats list"
|
|
10
10
|
];
|
|
11
11
|
static scope = "chats:read";
|
|
12
12
|
static apiMethod = "GET";
|
|
@@ -24,7 +24,7 @@ export default class SecurityList extends BaseCommand {
|
|
|
24
24
|
}),
|
|
25
25
|
'event-key': Flags.string({
|
|
26
26
|
description: "Фильтр по конкретному типу события",
|
|
27
|
-
options: ["user_login", "user_logout", "user_2fa_fail", "user_2fa_success", "user_created", "user_deleted", "user_role_changed", "user_updated", "tag_created", "tag_deleted", "user_added_to_tag", "user_removed_from_tag", "chat_created", "chat_renamed", "chat_permission_changed", "user_chat_join", "user_chat_leave", "tag_added_to_chat", "tag_removed_from_chat", "message_updated", "message_deleted", "message_created", "reaction_created", "reaction_deleted", "thread_created", "access_token_created", "access_token_updated", "access_token_destroy", "kms_encrypt", "kms_decrypt", "audit_events_accessed", "dlp_violation_detected", "search_users_api", "search_chats_api", "search_messages_api", "bot_scopes_updated", "bot_webhook_settings_updated", "bot_token_recreated", "bot_deleted", "bot_oauth_client_updated", "oauth_authorization_granted", "oauth_authorization_revoked", "video_call_started", "video_call_finished", "video_call_recording_ready"],
|
|
27
|
+
options: ["user_login", "user_logout", "user_2fa_fail", "user_2fa_success", "user_created", "user_deleted", "user_role_changed", "user_updated", "tag_created", "tag_deleted", "user_added_to_tag", "user_removed_from_tag", "chat_created", "chat_renamed", "chat_permission_changed", "user_chat_join", "user_chat_leave", "tag_added_to_chat", "tag_removed_from_chat", "message_updated", "message_deleted", "message_created", "reaction_created", "reaction_deleted", "thread_created", "access_token_created", "access_token_updated", "access_token_destroy", "kms_encrypt", "kms_decrypt", "audit_events_accessed", "company_chats_accessed", "company_bots_accessed", "dlp_violation_detected", "search_users_api", "search_chats_api", "search_messages_api", "bot_scopes_updated", "bot_webhook_settings_updated", "bot_token_recreated", "bot_deleted", "bot_oauth_client_updated", "oauth_authorization_granted", "oauth_authorization_revoked", "video_call_started", "video_call_finished", "video_call_recording_ready"],
|
|
28
28
|
}),
|
|
29
29
|
'actor-id': Flags.string({
|
|
30
30
|
description: "Идентификатор пользователя, выполнившего действие",
|
|
@@ -4,7 +4,9 @@ import { BaseCommand } from '../../base-command.js';
|
|
|
4
4
|
export default class TasksList extends BaseCommand {
|
|
5
5
|
static description = "Список напоминаний";
|
|
6
6
|
static examples = [
|
|
7
|
-
"Получить список предстоящих задач — Получи
|
|
7
|
+
"Получить список предстоящих задач — Получи невыполненные задачи:\n $ pachca tasks list",
|
|
8
|
+
"Собрать задачи по чатам проекта — Запроси задачи нужных чатов:\n $ pachca tasks list",
|
|
9
|
+
"Собрать задачи по чатам проекта — Сузь выборку по автору, ответственным и состоянию:\n $ pachca tasks list"
|
|
8
10
|
];
|
|
9
11
|
static scope = "tasks:read";
|
|
10
12
|
static apiMethod = "GET";
|
|
@@ -13,6 +15,19 @@ export default class TasksList extends BaseCommand {
|
|
|
13
15
|
static args = {};
|
|
14
16
|
static flags = {
|
|
15
17
|
...BaseCommand.baseFlags,
|
|
18
|
+
'status': Flags.string({
|
|
19
|
+
description: "Фильтр по состоянию. Если параметр не указан, возвращаются напоминания в любом состоянии.",
|
|
20
|
+
options: ["done", "undone"],
|
|
21
|
+
}),
|
|
22
|
+
'chat-ids': Flags.string({
|
|
23
|
+
description: "Фильтр по чатам, к которым привязаны напоминания. Доступными считаются чаты, где вы состоите участником, открытые беседы и каналы пространства, а также треды, доступные вам по родительскому чату. Остальные переданные идентификаторы игнорируются без ошибки. Не более 100 идентификаторов." + " (через запятую)",
|
|
24
|
+
}),
|
|
25
|
+
'performer-ids': Flags.string({
|
|
26
|
+
description: "Фильтр по ответственным за напоминание. Не более 100 идентификаторов." + " (через запятую)",
|
|
27
|
+
}),
|
|
28
|
+
'author-id': Flags.integer({
|
|
29
|
+
description: "Фильтр по автору напоминания",
|
|
30
|
+
}),
|
|
16
31
|
limit: Flags.integer({
|
|
17
32
|
description: 'Количество результатов на страницу',
|
|
18
33
|
}),
|
|
@@ -35,6 +50,10 @@ export default class TasksList extends BaseCommand {
|
|
|
35
50
|
const seenCursors = new Set();
|
|
36
51
|
while (pages < 500) {
|
|
37
52
|
const query = {
|
|
53
|
+
status: flags['status'],
|
|
54
|
+
'chat_ids': flags['chat-ids']?.split(','),
|
|
55
|
+
'performer_ids': flags['performer-ids']?.split(','),
|
|
56
|
+
'author_id': flags['author-id'],
|
|
38
57
|
limit: flags.limit,
|
|
39
58
|
cursor: nextCursor,
|
|
40
59
|
};
|
|
@@ -81,6 +100,10 @@ export default class TasksList extends BaseCommand {
|
|
|
81
100
|
method: 'GET',
|
|
82
101
|
path: '/tasks',
|
|
83
102
|
query: {
|
|
103
|
+
status: flags['status'],
|
|
104
|
+
'chat_ids': flags['chat-ids']?.split(','),
|
|
105
|
+
'performer_ids': flags['performer-ids']?.split(','),
|
|
106
|
+
'author_id': flags['author-id'],
|
|
84
107
|
limit: flags.limit,
|
|
85
108
|
cursor: flags.cursor,
|
|
86
109
|
},
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
"members:remove": "Исключение пользователя",
|
|
24
24
|
"members:update": "Редактирование роли",
|
|
25
25
|
"chats:unarchive": "Разархивация чата",
|
|
26
|
+
"bots:list-company": "Список ботов пространства",
|
|
27
|
+
"chats:list-company": "Список чатов пространства",
|
|
26
28
|
"custom-properties:list": "Список дополнительных полей",
|
|
27
29
|
"files:direct-url": "Загрузка файла",
|
|
28
30
|
"group-tags:create": "Новый тег",
|
package/dist/data/changelog.json
CHANGED
|
@@ -1,7 +1,37 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "2026.8.2",
|
|
4
|
+
"date": "12 августа 2026",
|
|
5
|
+
"changes": [
|
|
6
|
+
{
|
|
7
|
+
"type": "+",
|
|
8
|
+
"command": "chats list-company",
|
|
9
|
+
"description": "Новая команда — все беседы и каналы пространства, включая закрытые, где вы не состоите. Флаг `--activity` со значением `active` или `archived` оставляет одно состояние, по умолчанию отдаются оба. Нужна роль владельца пространства, тариф «Корпорация» и право `company_chats:read`"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "+",
|
|
13
|
+
"command": "bots list-company",
|
|
14
|
+
"description": "Новая команда — все боты пространства, включая недоступные вам для редактирования. У таких ботов заполнены только имя и никнейм, остальные настройки приходят пустыми. Фильтр по имени — флаг `--query`. Нужна роль владельца пространства, тариф «Корпорация» и право `company_bots:read`"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "+",
|
|
18
|
+
"command": "tasks list",
|
|
19
|
+
"description": "Флаги `--status`, `--chat-ids`, `--performer-ids` и `--author-id` для фильтрации напоминаний. С `--chat-ids` выдача расширяется до всех напоминаний указанных чатов, а не только ваших"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "+",
|
|
23
|
+
"command": "security list",
|
|
24
|
+
"description": "Фильтр `--event-key` принимает `company_chats_accessed` и `company_bots_accessed`"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "-",
|
|
28
|
+
"description": "Недостающий скоуп в ошибке `insufficient_scope` берётся из заголовка `WWW-Authenticate` — раньше его вытаскивали регуляркой из текста сообщения, и он терялся при любой смене формулировки. Разбор текста остался запасным путём"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
2
32
|
{
|
|
3
33
|
"version": "2026.8.1",
|
|
4
|
-
"date": "
|
|
34
|
+
"date": "7 августа 2026",
|
|
5
35
|
"changes": [
|
|
6
36
|
{
|
|
7
37
|
"type": "+",
|