@pachca/cli 2026.9.1 → 2026.10.1

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.
Files changed (76) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +17 -5
  3. package/dist/base-command.js +47 -0
  4. package/dist/client.js +2 -1
  5. package/dist/commands/auth/login.js +4 -4
  6. package/dist/commands/bots/create-token.js +84 -0
  7. package/dist/commands/bots/create.js +33 -6
  8. package/dist/commands/bots/delete-token.js +46 -0
  9. package/dist/commands/bots/delete.js +1 -1
  10. package/dist/commands/bots/get.js +1 -1
  11. package/dist/commands/bots/list-company.js +1 -1
  12. package/dist/commands/bots/list-events.js +1 -1
  13. package/dist/commands/bots/list-scopes.js +32 -0
  14. package/dist/commands/bots/list-tokens.js +94 -0
  15. package/dist/commands/bots/list.js +3 -3
  16. package/dist/commands/bots/recreate-token-self.js +1 -1
  17. package/dist/commands/bots/recreate-token.js +2 -2
  18. package/dist/commands/bots/reissue-token.js +37 -0
  19. package/dist/commands/bots/remove-avatar.js +42 -0
  20. package/dist/commands/bots/remove-event.js +1 -1
  21. package/dist/commands/bots/rotate-client-secret.js +30 -0
  22. package/dist/commands/bots/update-avatar.js +51 -0
  23. package/dist/commands/bots/update-token.js +60 -0
  24. package/dist/commands/bots/update.js +37 -8
  25. package/dist/commands/chats/create.js +1 -0
  26. package/dist/commands/chats/download-export.js +1 -1
  27. package/dist/commands/chats/get.js +1 -1
  28. package/dist/commands/chats/list-company.js +1 -1
  29. package/dist/commands/chats/list.js +1 -1
  30. package/dist/commands/chats/mark-unread.js +44 -0
  31. package/dist/commands/chats/remove-avatar.js +45 -0
  32. package/dist/commands/chats/request-export.js +4 -2
  33. package/dist/commands/chats/update-avatar.js +54 -0
  34. package/dist/commands/drafts/create.js +1 -1
  35. package/dist/commands/drafts/list.js +1 -1
  36. package/dist/commands/drafts/update.js +1 -1
  37. package/dist/commands/files/direct-url.js +8 -4
  38. package/dist/commands/group-tags/get.js +1 -1
  39. package/dist/commands/group-tags/list-users.js +2 -2
  40. package/dist/commands/group-tags/list.js +3 -3
  41. package/dist/commands/members/add.js +2 -2
  42. package/dist/commands/members/list.js +2 -2
  43. package/dist/commands/members/remove-group-tag.js +1 -1
  44. package/dist/commands/members/remove.js +1 -1
  45. package/dist/commands/members/update.js +1 -1
  46. package/dist/commands/messages/create.js +9 -10
  47. package/dist/commands/messages/get.js +1 -1
  48. package/dist/commands/messages/list.js +1 -1
  49. package/dist/commands/messages/update.js +2 -2
  50. package/dist/commands/profile/update-status.js +3 -32
  51. package/dist/commands/reactions/list.js +1 -1
  52. package/dist/commands/read-member/list-readers.js +1 -1
  53. package/dist/commands/search/list-chats.js +2 -2
  54. package/dist/commands/search/list-messages.js +6 -6
  55. package/dist/commands/search/list-users.js +4 -4
  56. package/dist/commands/security/list.js +2 -2
  57. package/dist/commands/tasks/create.js +1 -1
  58. package/dist/commands/tasks/get.js +1 -1
  59. package/dist/commands/tasks/list.js +6 -6
  60. package/dist/commands/tasks/update.js +1 -1
  61. package/dist/commands/threads/get.js +1 -1
  62. package/dist/commands/threads/list.js +2 -2
  63. package/dist/commands/upload.js +5 -2
  64. package/dist/commands/users/create.js +1 -1
  65. package/dist/commands/users/get.js +1 -1
  66. package/dist/commands/users/list.js +1 -1
  67. package/dist/commands/users/update-status.js +3 -32
  68. package/dist/commands/users/update.js +2 -2
  69. package/dist/commands/views/open.js +2 -2
  70. package/dist/data/alternatives.json +17 -5
  71. package/dist/data/changelog.json +146 -0
  72. package/dist/data/endpoints.json +1 -1
  73. package/dist/data/workflows.json +60 -9
  74. package/dist/oauth.js +28 -3
  75. package/oclif.manifest.json +1 -1
  76. package/package.json +1 -1
@@ -46,16 +46,19 @@ export default class Upload extends BaseCommand {
46
46
  }
47
47
  // Step 3: Replace ${filename} in key
48
48
  const key = params.key.replace('${filename}', fileName);
49
- // Step 4: Build FormData
49
+ // Step 4: Build FormData. A workspace gets `acl` or `bucket`, depending on its storage
50
50
  const formData = new FormData();
51
51
  formData.append('Content-Disposition', params['Content-Disposition']);
52
- formData.append('acl', params.acl);
52
+ if (params.acl !== undefined)
53
+ formData.append('acl', params.acl);
53
54
  formData.append('policy', params.policy);
54
55
  formData.append('x-amz-credential', params['x-amz-credential']);
55
56
  formData.append('x-amz-algorithm', params['x-amz-algorithm']);
56
57
  formData.append('x-amz-date', params['x-amz-date']);
57
58
  formData.append('x-amz-signature', params['x-amz-signature']);
58
59
  formData.append('key', key);
60
+ if (params.bucket !== undefined)
61
+ formData.append('bucket', params.bucket);
59
62
  formData.append('file', fileBlob, fileName);
60
63
  // Step 5: Upload to external URL (no auth)
61
64
  await this.apiRequest({
@@ -46,7 +46,7 @@ export default class UsersCreate extends BaseCommand {
46
46
  allowNo: true,
47
47
  }),
48
48
  'list-tags': Flags.string({
49
- description: "Массив тегов, привязываемых к сотруднику",
49
+ description: "Массив названий тегов, привязываемых к сотруднику. Значение, которое не является массивом непустых строк, игнорируется.",
50
50
  }),
51
51
  'chat-ids': Flags.string({
52
52
  description: "Идентификаторы чатов, в которые сотрудник будет добавлен сразу при создании. Для роли `guest` параметр обязателен и должен содержать ровно один активный чат.",
@@ -12,7 +12,7 @@ export default class UsersGet extends BaseCommand {
12
12
  static defaultColumns = ["id", "title", "first_name", "last_name", "email"];
13
13
  static args = {
14
14
  id: Args.integer({
15
- description: "Идентификатор пользователя (pachca users list)",
15
+ description: "Идентификатор пользователя. В ссылке веб-приложения это число из параметра `user_id`. Параметры `profile_id` и `user-id` называют сотрудника, которому ссылку отправили. (pachca users list)",
16
16
  required: true,
17
17
  }),
18
18
  };
@@ -53,7 +53,7 @@ export default class UsersList extends BaseCommand {
53
53
  const paginate = meta?.paginate;
54
54
  nextCursor = paginate?.next_page;
55
55
  pages++;
56
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
56
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
57
57
  const hasNext = paginate?.has_next;
58
58
  if (typeof hasNext === 'boolean') {
59
59
  if (!hasNext)
@@ -1,7 +1,6 @@
1
1
  // Auto-generated from openapi.yaml — DO NOT EDIT
2
2
  import { Args, Flags } from '@oclif/core';
3
3
  import { BaseCommand } from '../../base-command.js';
4
- import * as clack from '@clack/prompts';
5
4
  export default class UsersUpdateStatus extends BaseCommand {
6
5
  static description = "Новый статус сотрудника";
7
6
  static examples = [
@@ -11,7 +10,6 @@ export default class UsersUpdateStatus extends BaseCommand {
11
10
  static apiMethod = "PUT";
12
11
  static apiPath = "/users/{user_id}/status";
13
12
  static defaultColumns = ["title", "emoji", "expires_at", "is_away"];
14
- static requiredFlags = ["emoji", "title"];
15
13
  static args = {
16
14
  user_id: Args.integer({
17
15
  description: "Идентификатор пользователя (pachca users list)",
@@ -21,13 +19,13 @@ export default class UsersUpdateStatus extends BaseCommand {
21
19
  static flags = {
22
20
  ...BaseCommand.baseFlags,
23
21
  'emoji': Flags.string({
24
- description: "Emoji символ статуса",
22
+ description: "Emoji символ статуса. Обязателен, если статуса ещё нет.",
25
23
  }),
26
24
  'title': Flags.string({
27
- description: "Текст статуса (макс. 50 символов)",
25
+ description: "Текст статуса. Обязателен, если статуса ещё нет. (макс. 50 символов)",
28
26
  }),
29
27
  'expires-at': Flags.string({
30
- description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC. Сюда идёт срок, названный словами: «до трёх» это значение поля, а не часть подписи.",
28
+ description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC.",
31
29
  }),
32
30
  'is-away': Flags.boolean({
33
31
  description: "Режим «Нет на месте»",
@@ -40,33 +38,6 @@ export default class UsersUpdateStatus extends BaseCommand {
40
38
  async run() {
41
39
  const { args, flags } = await this.parse(UsersUpdateStatus);
42
40
  this.parsedFlags = flags;
43
- const missingRequired = [
44
- { flag: 'emoji', label: "Emoji символ статуса", type: 'string' },
45
- { flag: 'title', label: "Текст статуса", type: 'string' },
46
- ].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
47
- if (missingRequired.length > 0) {
48
- if (this.isInteractive()) {
49
- for (const field of missingRequired) {
50
- const value = await clack.text({ message: field.label, validate: (v) => v.length === 0 ? 'Обязательное поле' : undefined });
51
- if (clack.isCancel(value)) {
52
- process.stderr.write('Отменено.\n');
53
- this.exit(0);
54
- }
55
- if (field.type === 'integer') {
56
- flags[field.flag] = Number.parseInt(value, 10);
57
- }
58
- else if (field.type === 'boolean') {
59
- flags[field.flag] = value === 'true';
60
- }
61
- else {
62
- flags[field.flag] = value;
63
- }
64
- }
65
- }
66
- else {
67
- this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --emoji <string>, --title <string>. pachca introspect users update-status" });
68
- }
69
- }
70
41
  const validationErrors = [];
71
42
  if (flags['title'] && String(flags['title']).length > 50) {
72
43
  validationErrors.push({ message: `--title: максимум 50 символов (передано: ${String(flags['title']).length})`, flag: 'title' });
@@ -32,7 +32,7 @@ export default class UsersUpdate extends BaseCommand {
32
32
  description: "Телефон (макс. 255 символов)",
33
33
  }),
34
34
  'nickname': Flags.string({
35
- description: "Имя пользователя (макс. 255 символов)",
35
+ description: "Имя пользователя. Ник бота должен оканчиваться на `_bot` и быть уникальным в пространстве, иначе метод отвечает `422` с ошибкой на поле `nickname`: `invalid` или `already_exists`. Прежний ник бота проверяется, только когда его меняют. (макс. 255 символов)",
36
36
  }),
37
37
  'department': Flags.string({
38
38
  description: "Департамент (макс. 255 символов)",
@@ -48,7 +48,7 @@ export default class UsersUpdate extends BaseCommand {
48
48
  allowNo: true,
49
49
  }),
50
50
  'list-tags': Flags.string({
51
- description: "Массив тегов, привязываемых к сотруднику",
51
+ description: "Массив названий тегов, привязываемых к сотруднику. Список заменяет прежний целиком, пустой снимает все теги. Значение, которое не является массивом непустых строк, игнорируется: теги сотрудника не меняются. В тег можно добавить только бота, которого может добавить в чат любой сотрудник и у которого выключена настройка «Ограничить одним чатом». Если бот этим условиям не отвечает, а в списке есть тег, которого у него ещё нет, метод отвечает `422` на поле `group_tags` и ничего не меняет: с кодом `single_chat_bot_tag_denied`, когда бот ограничен одним чатом, и `restricted_bot_tag_denied`, когда добавлять его в чаты могут не все. Подробнее — в разделе [Бот в тегах](https://dev.pachca.com/guides/bots/settings#bot-v-tegah).",
52
52
  }),
53
53
  'custom-properties': Flags.string({
54
54
  description: "Задаваемые дополнительные поля",
@@ -26,7 +26,7 @@ export default class ViewsOpen extends BaseCommand {
26
26
  description: "Текст кнопки отправки формы (макс. 24 символов)",
27
27
  }),
28
28
  'blocks': Flags.string({
29
- description: "Массив блоков представления",
29
+ description: "Массив блоков представления. Имена блоков (`name`) не повторяются, в select и radio заранее выбрано не больше одного варианта, а `min_length` поля ввода не больше его `max_length`.",
30
30
  }),
31
31
  'type': Flags.string({
32
32
  description: "Способ открытия представления",
@@ -47,7 +47,7 @@ export default class ViewsOpen extends BaseCommand {
47
47
  this.parsedFlags = flags;
48
48
  const missingRequired = [
49
49
  { flag: 'title', label: "Заголовок представления", type: 'string' },
50
- { flag: 'blocks', label: "Массив блоков представления", type: 'string' },
50
+ { flag: 'blocks', label: "Массив блоков представления. Имена блоков (`name`) не повторяются, в select и radio заранее выбрано не больше одного варианта, а `min_length` поля ввода не больше его `max_length`.", type: 'string' },
51
51
  { flag: 'type', label: "Способ открытия представления", type: 'string' },
52
52
  { flag: 'trigger-id', label: "Уникальный идентификатор события (полученный, например, в исходящем вебхуке о нажатии кнопки)", type: 'string' },
53
53
  ].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
@@ -7,7 +7,16 @@
7
7
  "bots:get": "Информация о боте",
8
8
  "bots:update": "Редактирование бота",
9
9
  "bots:delete": "Удаление бота",
10
+ "bots:update-avatar": "Загрузка аватара бота",
11
+ "bots:remove-avatar": "Удаление аватара бота",
10
12
  "bots:recreate-token": "Ротация токена бота",
13
+ "bots:rotate-client-secret": "Ротация секрета клиента",
14
+ "bots:list-scopes": "Каталог прав бота",
15
+ "bots:list-tokens": "Список токенов бота",
16
+ "bots:create-token": "Новый токен бота",
17
+ "bots:update-token": "Изменение токена бота",
18
+ "bots:delete-token": "Удаление токена бота",
19
+ "bots:reissue-token": "Перевыпуск токена бота",
11
20
  "chats:create": "Новый чат",
12
21
  "chats:list": "Список чатов",
13
22
  "chats:request-export": "Экспорт сообщений",
@@ -15,14 +24,17 @@
15
24
  "chats:get": "Информация о чате",
16
25
  "chats:update": "Редактирование чата",
17
26
  "chats:archive": "Архивация чата",
27
+ "chats:update-avatar": "Загрузка аватара чата",
28
+ "chats:remove-avatar": "Удаление аватара чата",
18
29
  "members:add-group-tags": "Добавление тегов",
19
- "members:remove-group-tag": "Исключение тега",
30
+ "members:remove-group-tag": "Исключение тега из чата",
20
31
  "members:leave": "Выход из чата",
21
32
  "members:list": "Список участников чата",
22
- "members:add": "Добавление пользователей",
23
- "members:remove": "Исключение пользователя",
24
- "members:update": "Редактирование роли",
33
+ "members:add": "Добавление участников",
34
+ "members:remove": "Исключение участника",
35
+ "members:update": "Редактирование роли участника",
25
36
  "chats:unarchive": "Разархивация чата",
37
+ "chats:mark-unread": "Отметка чата непрочитанным",
26
38
  "bots:list-company": "Список ботов пространства",
27
39
  "chats:list-company": "Список чатов пространства",
28
40
  "custom-properties:list": "Список дополнительных полей",
@@ -84,7 +96,7 @@
84
96
  "views:open": "Открытие представления",
85
97
  "views:submit-response": "Ответ на отправку формы",
86
98
  "bots:list-events": "История событий",
87
- "bots:remove-event": "Удаление события",
99
+ "bots:remove-event": "Удаление события истории",
88
100
  "skill:pachca-users": "pachca-users",
89
101
  "skill:pachca-oauth": "pachca-oauth",
90
102
  "skill:pachca-profile": "получить профиль, мой профиль, установить свой статус",
@@ -1,4 +1,150 @@
1
1
  [
2
+ {
3
+ "version": "2026.10.1",
4
+ "date": "20 октября 2026",
5
+ "changes": [
6
+ {
7
+ "type": "~",
8
+ "command": "chats request-export",
9
+ "description": "Команда выводит номер выгрузки `id`: с ним `pachca chats download-export` забирает архив, когда тот соберётся"
10
+ },
11
+ {
12
+ "type": "+",
13
+ "command": "chats create",
14
+ "description": "Команда предупреждает в stderr об идентификаторах из `--member-ids`, которых не удалось добавить в чат"
15
+ },
16
+ {
17
+ "type": "+",
18
+ "command": "bots update-avatar, bots remove-avatar",
19
+ "description": "Новые команды — аватар бота: загрузка файла флагом `--file` и удаление"
20
+ },
21
+ {
22
+ "type": "+",
23
+ "command": "bots get",
24
+ "description": "В `webhook` приходят адрес входящего вебхука `url`, секрет подписи `secret_token` и тело последнего запроса `last_request_body`, если у токена есть скоуп `bots:write` и вы можете управлять токенами бота"
25
+ },
26
+ {
27
+ "type": "~",
28
+ "command": "messages create",
29
+ "description": "Сообщение уходит без `--content`, если к нему приложены файлы"
30
+ },
31
+ {
32
+ "type": "~",
33
+ "command": "profile update-status, users update-status",
34
+ "description": "`--emoji` и `--title` нужны, только когда статуса ещё нет — продлить статус можно одним `--expires-at`"
35
+ },
36
+ {
37
+ "type": "~",
38
+ "command": "upload, files direct-url",
39
+ "description": "`pachca upload` передаёт в форме загрузки `acl` и `bucket`, только если они пришли, а у `pachca files direct-url` флаг `--acl` необязателен и есть флаг `--bucket`: в части пространств метод `Получение подписи, ключа и других параметров` отдаёт `bucket` вместо `acl`"
40
+ }
41
+ ]
42
+ },
43
+ {
44
+ "version": "2026.10.0",
45
+ "date": "13 октября 2026",
46
+ "changes": [
47
+ {
48
+ "type": "+",
49
+ "command": "bots list-tokens, bots create-token, bots update-token, bots reissue-token, bots delete-token",
50
+ "description": "Новые команды — токены бота: у бота может быть несколько токенов, у каждого своё имя и права. Значение токена показывается один раз, при выпуске и перевыпуске."
51
+ },
52
+ {
53
+ "type": "+",
54
+ "command": "bots list-scopes",
55
+ "description": "Новая команда — каталог прав, которые можно выдать боту: его токенам и авторизации от имени сотрудника"
56
+ },
57
+ {
58
+ "type": "+",
59
+ "command": "bots rotate-client-secret",
60
+ "description": "Новая команда — новый `client_secret` для авторизации от имени сотрудника. Прежний секрет перестаёт работать сразу."
61
+ },
62
+ {
63
+ "type": "+",
64
+ "command": "bots create, bots update",
65
+ "description": "Флаги `--oauth-client` и `--promo` включают авторизацию от имени сотрудника и заполняют страницу бота в витрине, `--kind` выбирает источник входящего вебхука, а `--unfurl-domains` задаёт домены для разворачивания ссылок. У `bots create` появился `--empty` для бота без токена, у `bots update` — `--single-chat`."
66
+ },
67
+ {
68
+ "type": "+",
69
+ "command": "chats mark-unread",
70
+ "description": "Новая команда — отметка чата непрочитанным для владельца токена"
71
+ },
72
+ {
73
+ "type": "+",
74
+ "command": "chats update-avatar, chats remove-avatar",
75
+ "description": "Новые команды — аватар беседы или канала: загрузка файла флагом `--file` и удаление. В выводе команд с чатами появилось поле `avatar_url`."
76
+ },
77
+ {
78
+ "type": "+",
79
+ "command": "security list",
80
+ "description": "Флаг `--event-key` принимает значения `bot_token_created`, `bot_token_updated`, `bot_token_reissued`, `bot_token_deleted`, `bot_oauth_client_secret_issued`, `bot_oauth_client_secret_rotated`, `bot_oauth_client_disabled` и `oauth_token_revoked`"
81
+ },
82
+ {
83
+ "type": "-",
84
+ "command": "search users, search chats, search messages, users list",
85
+ "description": "В справке описан ответ `504` с кодом `timeout`, если поиск не уложился по времени"
86
+ },
87
+ {
88
+ "type": "-",
89
+ "command": "messages create, messages update, drafts create, drafts update",
90
+ "description": "У файлов в справке указан предел голосового сообщения в 30 минут"
91
+ },
92
+ {
93
+ "type": "+",
94
+ "command": "auth login",
95
+ "description": "Вход через браузер передаёт серверу имя устройства, по которому вход узнаётся в списке токенов CLI: имя машины, а у профиля не по умолчанию ещё и имя профиля в скобках, например `macbook (ci)`"
96
+ },
97
+ {
98
+ "type": "~",
99
+ "description": "После ответа `401` CLI подсказывает, что делать дальше: войти заново, если вход через браузер отозван или завершён, или сохранить новый токен. В подсказку подставлен профиль, с которым запускалась команда, например `pachca auth login --profile ci`"
100
+ },
101
+ {
102
+ "type": "-",
103
+ "command": "views open",
104
+ "description": "В справке у блоков `radio` и `checkbox` до 20 вариантов"
105
+ },
106
+ {
107
+ "type": "-",
108
+ "command": "bots create, bots update",
109
+ "description": "Справка к `--ignore-self-messages` говорит, что настройка не присылает боту и его собственные реакции"
110
+ },
111
+ {
112
+ "type": "-",
113
+ "command": "guide",
114
+ "description": "Сценарии разворачивания ссылок и поллинга описывают раздел «Интеграции»: событие ссылок с доменами вместо отдельного типа бота и история событий без Webhook URL флагом `--events-history-enabled`, который попал и в примеры `bots update`"
115
+ },
116
+ {
117
+ "type": "-",
118
+ "command": "messages create, messages update, tasks list",
119
+ "description": "Подсказки к `--content` и `--chat-ids` описывают, что меняется для мульти-гостя"
120
+ },
121
+ {
122
+ "type": "-",
123
+ "command": "messages create, messages update, drafts create, drafts update, tasks create, tasks update",
124
+ "description": "В справке к `--content` указан предел длины текста: 40 000 байт, а в пространстве с продвинутым шифрованием 27 000"
125
+ },
126
+ {
127
+ "type": "-",
128
+ "command": "messages create, threads add, threads create, threads get, threads list",
129
+ "description": "Подсказка к `--parent-message-id` описывает ответ с цитатой в любом чате, в том числе в треде. В описаниях тредов сказано, какой идентификатор куда передавать: `id` — чтобы написать в тред, `chat_id` — чтобы прочитать его сообщения."
130
+ },
131
+ {
132
+ "type": "-",
133
+ "command": "bots list-events",
134
+ "description": "В справке у события отправки формы сказано, что `chat_id` фиксируется при открытии формы, а не при её отправке"
135
+ },
136
+ {
137
+ "type": "-",
138
+ "command": "chats create, members add, users update",
139
+ "description": "В справке описаны отказы для бота с настройкой «Ограничить одним чатом» — `single_chat_bot_occupied`, если он уже состоит в другой беседе или канале, и `single_chat_bot_tag_denied` при добавлении в тег. У `users update` сказано, что у бота меняются только имя, ник, теги и `suspended`."
140
+ },
141
+ {
142
+ "type": "-",
143
+ "command": "tasks get",
144
+ "description": "В справке сказано, что напоминание видят все, кому доступен его чат, по тому же правилу, что у фильтра `--chat-ids` в `tasks list`"
145
+ }
146
+ ]
147
+ },
2
148
  {
3
149
  "version": "2026.9.1",
4
150
  "date": "16 сентября 2026",