@pachca/cli 2026.6.3 → 2026.7.0

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.7.0 (7 июля 2026)
4
+
5
+ - **Добавлено** (bots list): Новая команда — список ботов с поиском по имени (`--query`)
6
+ - **Добавлено** (bots delete): Новая команда — удаление бота по его `id`
7
+ - **Добавлено** (bots create): Права доступа бота — параметры `who-can-add` (кто может добавлять бота в чаты), `can-edit` (роли, редактирующие настройки) и `single-chat` (только один чат)
8
+ - **Добавлено** (bots update): Права доступа бота — параметры `who-can-add` (кто может добавлять бота в чаты) и `can-edit` (роли, редактирующие настройки)
9
+ - **Добавлено** (search users): Значение сортировки `--sort creation` — по дате создания
10
+
3
11
  ## 2026.6.3 (24 июня 2026)
4
12
 
5
13
  - **Изменено** (files, custom-properties, oauth): Команды реорганизованы по разделам: `common uploads`→`files uploads`, `common direct-url`→`files direct-url`, `common custom-properties`→`custom-properties list`, `common request-export`→`chats request-export`, `common get-exports`→`chats download-export`, `profile get-info`→`oauth token-info`, `link-previews add`→`messages unfurl`. Старые имена продолжают работать (скрытые алиасы)
package/README.md CHANGED
@@ -80,9 +80,11 @@ pachca guide # список всех сценариев
80
80
  |---------|---------|
81
81
  | `pachca bots recreate-token-self` | Ротация собственного токена бота |
82
82
  | `pachca bots update-webhook` | Саморегистрация вебхука бота |
83
+ | `pachca bots list` | Список ботов |
83
84
  | `pachca bots create` | Новый бот |
84
85
  | `pachca bots get` | Информация о боте |
85
86
  | `pachca bots update` | Редактирование бота |
87
+ | `pachca bots delete` | Удаление бота |
86
88
  | `pachca bots recreate-token` | Ротация токена бота |
87
89
  | `pachca bots list-events` | История событий |
88
90
  | `pachca bots remove-event` | Удаление события |
@@ -6,7 +6,8 @@ export default class BotsCreate extends BaseCommand {
6
6
  static description = "Новый бот";
7
7
  static examples = [
8
8
  "Создать бота через API и получить токен:\n $ pachca bots create",
9
- "Настроить бота с исходящим вебхуком:\n $ pachca bots create"
9
+ "Настроить бота с исходящим вебхуком:\n $ pachca bots create",
10
+ "Найти и удалить бота:\n $ pachca bots list"
10
11
  ];
11
12
  static scope = "bots:write";
12
13
  static apiMethod = "POST";
@@ -58,6 +59,16 @@ export default class BotsCreate extends BaseCommand {
58
59
  description: "Сохранять историю событий бота для последующего получения через метод истории событий",
59
60
  allowNo: true,
60
61
  }),
62
+ 'who-can-add': Flags.string({
63
+ description: "Кто может добавлять бота в чаты",
64
+ }),
65
+ 'can-edit': Flags.string({
66
+ description: "Роли, которым, помимо создателя, разрешено редактировать настройки бота. Создатель может редактировать всегда. Пустой массив — редактировать может только создатель.",
67
+ }),
68
+ 'single-chat': Flags.boolean({
69
+ description: "Ограничивает бота одной беседой или каналом: `true` — бота можно добавить только в один такой чат, `false` — в несколько. Личные чаты и треды в ограничение не входят. Задаётся только при создании, при редактировании не меняется.",
70
+ allowNo: true,
71
+ }),
61
72
  };
62
73
  async run() {
63
74
  const { args, flags } = await this.parse(BotsCreate);
@@ -102,6 +113,9 @@ export default class BotsCreate extends BaseCommand {
102
113
  link_preview_enabled: flags['link-preview-enabled'],
103
114
  ignore_self_messages: flags['ignore-self-messages'],
104
115
  events_history_enabled: flags['events-history-enabled'],
116
+ who_can_add: flags['who-can-add'],
117
+ can_edit: flags['can-edit'] ? this.parseJSON(flags['can-edit'], 'can-edit') : undefined,
118
+ single_chat: flags['single-chat'],
105
119
  } };
106
120
  // Clean undefined fields
107
121
  const inner = body['webhook'];
@@ -0,0 +1,46 @@
1
+ // Auto-generated from openapi.yaml — DO NOT EDIT
2
+ import { Args, Flags } from '@oclif/core';
3
+ import { BaseCommand } from '../../base-command.js';
4
+ import * as clack from '@clack/prompts';
5
+ export default class BotsDelete extends BaseCommand {
6
+ static description = "Удаление бота";
7
+ static examples = [
8
+ "Обновить Webhook URL бота:\n $ pachca bots update",
9
+ "Найти и удалить бота:\n $ pachca bots delete"
10
+ ];
11
+ static scope = "bots:write";
12
+ static apiMethod = "DELETE";
13
+ static apiPath = "/bots/{id}";
14
+ static args = {
15
+ id: Args.integer({
16
+ description: "Идентификатор бота (pachca bots list)",
17
+ required: true,
18
+ }),
19
+ };
20
+ static flags = {
21
+ ...BaseCommand.baseFlags,
22
+ force: Flags.boolean({
23
+ description: 'Пропустить подтверждение',
24
+ default: false,
25
+ }),
26
+ };
27
+ async run() {
28
+ const { args, flags } = await this.parse(BotsDelete);
29
+ this.parsedFlags = flags;
30
+ if (!flags.force) {
31
+ if (!this.isInteractive()) {
32
+ this.validationError([{ message: 'Деструктивная операция требует флага --force', flag: 'force' }], { type: 'PACHCA_DESTRUCTIVE_OP_ERROR', hint: "pachca bots delete <id> --force" });
33
+ }
34
+ const confirm = await clack.confirm({ message: 'Вы уверены?' });
35
+ if (clack.isCancel(confirm) || !confirm) {
36
+ process.stderr.write('Отменено.\n');
37
+ this.exit(0);
38
+ }
39
+ }
40
+ const { data } = await this.apiRequest({
41
+ method: 'DELETE',
42
+ path: `/bots/${args.id}`,
43
+ });
44
+ this.success('Удалено');
45
+ }
46
+ }
@@ -4,7 +4,8 @@ import { BaseCommand } from '../../base-command.js';
4
4
  export default class BotsGet extends BaseCommand {
5
5
  static description = "Информация о боте";
6
6
  static examples = [
7
- "Обновить Webhook URL бота:\n $ pachca bots update"
7
+ "Обновить Webhook URL бота:\n $ pachca bots update",
8
+ "Найти и удалить бота:\n $ pachca bots delete"
8
9
  ];
9
10
  static scope = "bots:read";
10
11
  static apiMethod = "GET";
@@ -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 BotsList extends BaseCommand {
5
+ static description = "Список ботов";
6
+ static examples = [
7
+ "Создать бота через API и получить токен:\n $ pachca bots create",
8
+ "Настроить бота с исходящим вебхуком:\n $ pachca bots create",
9
+ "Найти и удалить бота:\n $ pachca bots list"
10
+ ];
11
+ static scope = "bots:read";
12
+ static apiMethod = "GET";
13
+ static apiPath = "/bots";
14
+ static defaultColumns = ["id", "webhook"];
15
+ static args = {};
16
+ static flags = {
17
+ ...BaseCommand.baseFlags,
18
+ 'query': Flags.string({
19
+ description: "Поисковая фраза для фильтрации ботов по имени",
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(BotsList);
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
+ query: flags['query'],
44
+ limit: flags.limit,
45
+ cursor: nextCursor,
46
+ };
47
+ const response = await this.apiRequest({ method: 'GET', path: '/bots', 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: '/bots',
89
+ query: {
90
+ query: flags['query'],
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
+ }
@@ -4,7 +4,8 @@ import { BaseCommand } from '../../base-command.js';
4
4
  export default class BotsUpdate extends BaseCommand {
5
5
  static description = "Редактирование бота";
6
6
  static examples = [
7
- "Обновить Webhook URL бота:\n $ pachca bots update"
7
+ "Обновить Webhook URL бота:\n $ pachca bots update",
8
+ "Найти и удалить бота:\n $ pachca bots delete"
8
9
  ];
9
10
  static scope = "bots:write";
10
11
  static apiMethod = "PUT";
@@ -60,6 +61,12 @@ export default class BotsUpdate extends BaseCommand {
60
61
  description: "Сохранять историю событий бота для последующего получения через метод истории событий",
61
62
  allowNo: true,
62
63
  }),
64
+ 'who-can-add': Flags.string({
65
+ description: "Кто может добавлять бота в чаты",
66
+ }),
67
+ 'can-edit': Flags.string({
68
+ description: "Роли, которым, помимо создателя, разрешено редактировать настройки бота. Создатель может редактировать всегда. Пустой массив — редактировать может только создатель.",
69
+ }),
63
70
  };
64
71
  async run() {
65
72
  const { args, flags } = await this.parse(BotsUpdate);
@@ -78,6 +85,8 @@ export default class BotsUpdate extends BaseCommand {
78
85
  link_preview_enabled: flags['link-preview-enabled'],
79
86
  ignore_self_messages: flags['ignore-self-messages'],
80
87
  events_history_enabled: flags['events-history-enabled'],
88
+ who_can_add: flags['who-can-add'],
89
+ can_edit: flags['can-edit'] ? this.parseJSON(flags['can-edit'], 'can-edit') : undefined,
81
90
  } };
82
91
  // Clean undefined fields
83
92
  const inner = body['webhook'];
@@ -20,7 +20,7 @@ export default class SearchListUsers extends BaseCommand {
20
20
  }),
21
21
  'sort': Flags.string({
22
22
  description: "Сортировка результатов",
23
- options: ["by_score", "alphabetical"],
23
+ options: ["by_score", "alphabetical", "creation"],
24
24
  }),
25
25
  'order': Flags.string({
26
26
  description: "Направление сортировки",
@@ -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"],
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"],
28
28
  }),
29
29
  'actor-id': Flags.string({
30
30
  description: "Идентификатор пользователя, выполнившего действие",
@@ -2,9 +2,11 @@
2
2
  "security:list": "Журнал аудита событий",
3
3
  "bots:recreate-token-self": "Ротация собственного токена бота",
4
4
  "bots:update-webhook": "Саморегистрация вебхука бота",
5
+ "bots:list": "Список ботов",
5
6
  "bots:create": "Новый бот",
6
7
  "bots:get": "Информация о боте",
7
8
  "bots:update": "Редактирование бота",
9
+ "bots:delete": "Удаление бота",
8
10
  "bots:recreate-token": "Ротация токена бота",
9
11
  "chats:create": "Новый чат",
10
12
  "chats:list": "Список чатов",
@@ -1,4 +1,35 @@
1
1
  [
2
+ {
3
+ "version": "2026.7.0",
4
+ "date": "7 июля 2026",
5
+ "changes": [
6
+ {
7
+ "type": "+",
8
+ "command": "bots list",
9
+ "description": "Новая команда — список ботов с поиском по имени (`--query`)"
10
+ },
11
+ {
12
+ "type": "+",
13
+ "command": "bots delete",
14
+ "description": "Новая команда — удаление бота по его `id`"
15
+ },
16
+ {
17
+ "type": "+",
18
+ "command": "bots create",
19
+ "description": "Права доступа бота — параметры `who-can-add` (кто может добавлять бота в чаты), `can-edit` (роли, редактирующие настройки) и `single-chat` (только один чат)"
20
+ },
21
+ {
22
+ "type": "+",
23
+ "command": "bots update",
24
+ "description": "Права доступа бота — параметры `who-can-add` (кто может добавлять бота в чаты) и `can-edit` (роли, редактирующие настройки)"
25
+ },
26
+ {
27
+ "type": "+",
28
+ "command": "search users",
29
+ "description": "Значение сортировки `--sort creation` — по дате создания"
30
+ }
31
+ ]
32
+ },
2
33
  {
3
34
  "version": "2026.6.3",
4
35
  "date": "24 июня 2026",