@pachca/cli 2026.9.0 → 2026.10.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 +32 -0
- package/README.md +23 -2
- package/dist/base-command.js +35 -0
- package/dist/client.js +23 -8
- package/dist/commands/auth/login.js +4 -4
- package/dist/commands/bots/create-token.js +84 -0
- package/dist/commands/bots/create.js +32 -5
- package/dist/commands/bots/delete-token.js +46 -0
- package/dist/commands/bots/delete.js +1 -1
- package/dist/commands/bots/get.js +1 -1
- package/dist/commands/bots/list-scopes.js +32 -0
- package/dist/commands/bots/list-tokens.js +94 -0
- package/dist/commands/bots/list.js +1 -1
- package/dist/commands/bots/recreate-token-self.js +1 -1
- package/dist/commands/bots/recreate-token.js +2 -2
- package/dist/commands/bots/reissue-token.js +37 -0
- package/dist/commands/bots/rotate-client-secret.js +30 -0
- package/dist/commands/bots/update-token.js +60 -0
- package/dist/commands/bots/update.js +35 -6
- package/dist/commands/chats/list.js +2 -2
- package/dist/commands/chats/mark-unread.js +44 -0
- package/dist/commands/chats/remove-avatar.js +45 -0
- package/dist/commands/chats/request-export.js +7 -8
- package/dist/commands/chats/update-avatar.js +54 -0
- package/dist/commands/drafts/create.js +98 -0
- package/dist/commands/drafts/delete.js +45 -0
- package/dist/commands/drafts/get.js +30 -0
- package/dist/commands/drafts/list.js +107 -0
- package/dist/commands/drafts/update.js +66 -0
- package/dist/commands/files/get.js +43 -0
- package/dist/commands/group-tags/list.js +1 -1
- package/dist/commands/members/leave.js +1 -1
- package/dist/commands/messages/create.js +5 -5
- package/dist/commands/messages/update.js +1 -1
- package/dist/commands/profile/update-status.js +1 -1
- package/dist/commands/reactions/add.js +2 -2
- package/dist/commands/reactions/remove.js +2 -2
- package/dist/commands/search/list-chats.js +1 -0
- package/dist/commands/security/list.js +3 -3
- package/dist/commands/tasks/create.js +2 -2
- package/dist/commands/tasks/list.js +1 -1
- package/dist/commands/tasks/update.js +3 -3
- package/dist/commands/threads/list.js +2 -2
- package/dist/commands/users/create.js +1 -1
- package/dist/commands/users/update-status.js +1 -1
- package/dist/commands/users/update.js +1 -1
- package/dist/data/alternatives.json +18 -2
- package/dist/data/changelog.json +140 -0
- package/dist/data/endpoints.json +1 -1
- package/dist/data/workflows.json +76 -5
- package/dist/oauth.js +28 -3
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/dist/data/workflows.json
CHANGED
|
@@ -270,6 +270,26 @@
|
|
|
270
270
|
}
|
|
271
271
|
]
|
|
272
272
|
},
|
|
273
|
+
{
|
|
274
|
+
"title": "Отправить сообщение позже или по расписанию",
|
|
275
|
+
"skill": "pachca-messages",
|
|
276
|
+
"steps": [
|
|
277
|
+
{
|
|
278
|
+
"description": "Найди чат, в который нужно написать",
|
|
279
|
+
"command": "pachca search list-chats --query=\"название\""
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"description": "Создай отложенное сообщение: `schedule.start_date` — когда отправить, `schedule.repetition.interval` — как повторять (`once`, если один раз)",
|
|
283
|
+
"command": "pachca drafts create --entity-type=discussion --entity-id=<chat_id> --content=\"Текст\" --schedule='{\"start_date\":\"2026-09-17T09:00:00Z\",\"repetition\":{\"interval\":\"once\"}}'",
|
|
284
|
+
"notes": "Время без смещения считается UTC: переведи местное время сотрудника сами или пришли со смещением. Повтор по дням недели — `interval: \"weekly\"` и `days` (0 — воскресенье). В ответе `next_send_at` — ближайшая отправка, сверься с ней."
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"description": "Чтобы отменить отправку — удали отложенное сообщение",
|
|
288
|
+
"command": "pachca drafts delete <ID>",
|
|
289
|
+
"notes": "Другого способа отменить нет: снять расписание правкой нельзя"
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
},
|
|
273
293
|
{
|
|
274
294
|
"title": "Создать канал и пригласить участников",
|
|
275
295
|
"skill": "pachca-chats",
|
|
@@ -323,6 +343,21 @@
|
|
|
323
343
|
}
|
|
324
344
|
]
|
|
325
345
|
},
|
|
346
|
+
{
|
|
347
|
+
"title": "Поставить или убрать аватар чата",
|
|
348
|
+
"skill": "pachca-chats",
|
|
349
|
+
"steps": [
|
|
350
|
+
{
|
|
351
|
+
"description": "Загрузи аватар беседы или канала",
|
|
352
|
+
"command": "pachca chats update-avatar <ID> --file=<путь_к_файлу>",
|
|
353
|
+
"notes": "Файл передается в формате multipart/form-data: jpg, jpeg, png или gif. У личного чата и треда аватара нет — ответ 403"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"description": "Чтобы убрать аватар, удали его",
|
|
357
|
+
"command": "pachca chats remove-avatar <ID> --force"
|
|
358
|
+
}
|
|
359
|
+
]
|
|
360
|
+
},
|
|
326
361
|
{
|
|
327
362
|
"title": "Создать проектную беседу из шаблона",
|
|
328
363
|
"skill": "pachca-chats",
|
|
@@ -344,7 +379,7 @@
|
|
|
344
379
|
{
|
|
345
380
|
"description": "Запроси экспорт",
|
|
346
381
|
"command": "pachca chats request-export --start-at=<YYYY-MM-DD> --end-at=<YYYY-MM-DD> --webhook-url=<URL>",
|
|
347
|
-
"notes": "`start_at`, `end_at` (YYYY-MM-DD)
|
|
382
|
+
"notes": "`start_at`, `end_at` (YYYY-MM-DD). Запрос асинхронный: ответ приходит пустым, без номера выгрузки. `webhook_url` формально не обязателен, но без него номер взять неоткуда — присылай его всегда"
|
|
348
383
|
},
|
|
349
384
|
{
|
|
350
385
|
"description": "Скачай файл экспорта",
|
|
@@ -423,7 +458,7 @@
|
|
|
423
458
|
{
|
|
424
459
|
"description": "Пользовательским токеном (с правом редактировать бота) — обнови URL по `id` бота. Пустая строка отключает вебхук",
|
|
425
460
|
"command": "pachca bots update <bot_id> --outgoing-url=\"https://example.com/webhook\"",
|
|
426
|
-
"notes": "`id` бота
|
|
461
|
+
"notes": "`id` бота можно узнать методом `pachca bots list`"
|
|
427
462
|
},
|
|
428
463
|
{
|
|
429
464
|
"description": "Или: бот сам обновляет свой webhook своим же токеном — без `id` и без участия администратора (нужен скоуп `bot_self:webhook:write`)",
|
|
@@ -436,12 +471,44 @@
|
|
|
436
471
|
"skill": "pachca-bots",
|
|
437
472
|
"steps": [
|
|
438
473
|
{
|
|
439
|
-
"description": "Пользовательским токеном (администратор,
|
|
474
|
+
"description": "Пользовательским токеном (создатель бота или администратор, если бот открыт администраторам) — перевыпусти основной токен по `id` бота: тот, что без имени, а если такого нет, самый старый. Прежнее значение инвалидируется сразу",
|
|
440
475
|
"command": "pachca bots recreate-token <bot_id>"
|
|
441
476
|
},
|
|
442
477
|
{
|
|
443
|
-
"description": "Или: бот перевыпускает
|
|
478
|
+
"description": "Или: бот перевыпускает свой основной токен сам (скоуп `bot_self:write`). Если запрос сделан основным токеном, он инвалидируется сразу — обязательно сохрани новый `access_token` из ответа, иначе бот потеряет доступ к API",
|
|
444
479
|
"command": "pachca bots recreate-token-self"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
"description": "Отдельный токен бота перевыпускай по его `id` из `pachca bots list-tokens`: значение меняется, имя и права остаются",
|
|
483
|
+
"command": "pachca bots reissue-token <bot_id> <token_id>"
|
|
484
|
+
}
|
|
485
|
+
]
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
"title": "Выпустить боту отдельный токен",
|
|
489
|
+
"skill": "pachca-bots",
|
|
490
|
+
"steps": [
|
|
491
|
+
{
|
|
492
|
+
"description": "Пользовательским токеном (создатель бота или администратор, если бот открыт администраторам) получи каталог прав, которые можно выдать этому боту",
|
|
493
|
+
"command": "pachca bots list-scopes <bot_id>"
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"description": "Выпусти токен с именем и правами из каталога. Без `--scopes` токен выпускается без прав, право не из каталога отклоняется с `400`",
|
|
497
|
+
"command": "pachca bots create-token <bot_id> --name=\"Сервер уведомлений\" --scopes='[\"messages:create\"]'"
|
|
498
|
+
}
|
|
499
|
+
]
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
"title": "Включить боту авторизацию от имени сотрудника",
|
|
503
|
+
"skill": "pachca-bots",
|
|
504
|
+
"steps": [
|
|
505
|
+
{
|
|
506
|
+
"description": "Пользовательским токеном (создатель бота или администратор, если бот открыт администраторам) включи авторизацию: где хранится секрет, адреса возврата и права, которые бот попросит у сотрудника. Права бери из `pachca bots list-scopes`",
|
|
507
|
+
"command": "pachca bots update <bot_id> --oauth-client='{\"confidential\":true,\"redirect_uris\":[\"https://example.com/oauth/callback\"],\"scopes\":[\"messages:read\",\"messages:create\"]}'"
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
"description": "Чтобы бот появился в витрине, добавь описание и опубликуй страницу",
|
|
511
|
+
"command": "pachca bots update <bot_id> --promo='{\"description\":\"Собирает сводку по задачам\",\"published\":true}'"
|
|
445
512
|
}
|
|
446
513
|
]
|
|
447
514
|
},
|
|
@@ -454,7 +521,7 @@
|
|
|
454
521
|
"command": "pachca bots list --query=\"задач\""
|
|
455
522
|
},
|
|
456
523
|
{
|
|
457
|
-
"description": "Возьми `id` нужного бота из списка и удали его (скоуп `bots:write`). Доступно администратору,
|
|
524
|
+
"description": "Возьми `id` нужного бота из списка и удали его (скоуп `bots:write`). Доступно создателю бота и администратору, если бот открыт администраторам, — владельцы чатов удалять бота не могут. Все токены бота инвалидируются сразу, бот исключается из всех чатов, его вебхуки удаляются",
|
|
458
525
|
"command": "pachca bots delete <bot_id>"
|
|
459
526
|
}
|
|
460
527
|
]
|
|
@@ -519,6 +586,10 @@
|
|
|
519
586
|
"title": "Обработка событий через историю (polling)",
|
|
520
587
|
"skill": "pachca-bots",
|
|
521
588
|
"steps": [
|
|
589
|
+
{
|
|
590
|
+
"description": "Включи историю событий флагом `--events-history-enabled` (Webhook URL для этого не нужен) или настройкой «Сохранять историю событий» на вкладке «Исходящий вебхук» — в интерфейсе она появляется после включения вебхука",
|
|
591
|
+
"command": "pachca bots update <bot_id> --events-history-enabled"
|
|
592
|
+
},
|
|
522
593
|
{
|
|
523
594
|
"description": "Получи накопленные события",
|
|
524
595
|
"command": "pachca bots list-events --all"
|
package/dist/oauth.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn, spawnSync } from 'node:child_process';
|
|
2
|
+
import * as os from 'node:os';
|
|
2
3
|
import { getBaseUrl } from './client.js';
|
|
3
4
|
/** Uses the global timer on purpose: `node:timers/promises` is not fakeable in tests. */
|
|
4
5
|
function delay(ms) {
|
|
@@ -19,6 +20,8 @@ const DEVICE_CODE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
|
19
20
|
const MIN_POLL_INTERVAL_SECONDS = 5;
|
|
20
21
|
/** RFC 8628: on `slow_down` the client raises its interval by 5 seconds. */
|
|
21
22
|
const SLOW_DOWN_STEP_SECONDS = 5;
|
|
23
|
+
/** The backend keeps a device name of at most this many characters. */
|
|
24
|
+
const DEVICE_NAME_MAX_LENGTH = 255;
|
|
22
25
|
export class OAuthError extends Error {
|
|
23
26
|
code;
|
|
24
27
|
description;
|
|
@@ -76,9 +79,31 @@ async function postForm(endpoint, params) {
|
|
|
76
79
|
}
|
|
77
80
|
return body;
|
|
78
81
|
}
|
|
79
|
-
/**
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
/**
|
|
83
|
+
* What the token list on the «API» page calls this login.
|
|
84
|
+
*
|
|
85
|
+
* Every login is a row there, revoked one by one, so the rows have to tell
|
|
86
|
+
* machines apart: the machine name, plus the profile unless it is the default —
|
|
87
|
+
* two logins from one laptop differ by nothing else. The page joins a row's
|
|
88
|
+
* fields with « · », so the profile goes in parentheses rather than after one.
|
|
89
|
+
*/
|
|
90
|
+
export function deviceName(profile, hostname = os.hostname()) {
|
|
91
|
+
const machine = hostname.trim().replace(/\.local$/i, '');
|
|
92
|
+
const name = profile === 'default' ? machine : machine ? `${machine} (${profile})` : profile;
|
|
93
|
+
// Counted in characters, as the backend counts them, so a cut never splits one.
|
|
94
|
+
return Array.from(name).slice(0, DEVICE_NAME_MAX_LENGTH).join('') || undefined;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Step 1 — ask the server for a device code and the code the user types in.
|
|
98
|
+
*
|
|
99
|
+
* A server older than device names drops the extra parameter without a word,
|
|
100
|
+
* so it is sent regardless of which server the CLI talks to.
|
|
101
|
+
*/
|
|
102
|
+
export async function requestDeviceCode(device) {
|
|
103
|
+
const params = { client_id: CLI_CLIENT_ID };
|
|
104
|
+
if (device)
|
|
105
|
+
params.device_name = device;
|
|
106
|
+
const body = (await postForm('device_authorization', params));
|
|
82
107
|
if (!body?.device_code || !body.user_code || !body.verification_uri) {
|
|
83
108
|
throw new OAuthError('invalid_response', 'Сервер вернул неполный ответ на запрос кода');
|
|
84
109
|
}
|