@pachca/cli 2026.3.8 → 2026.3.10

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 (75) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/base-command.js +1 -43
  3. package/dist/commands/auth/list.js +0 -1
  4. package/dist/commands/auth/login.js +0 -9
  5. package/dist/commands/auth/status.js +0 -10
  6. package/dist/commands/bots/list-events.js +0 -1
  7. package/dist/commands/bots/remove-event.js +0 -1
  8. package/dist/commands/bots/update.js +0 -1
  9. package/dist/commands/chats/archive.js +0 -1
  10. package/dist/commands/chats/create.js +0 -1
  11. package/dist/commands/chats/get.js +0 -1
  12. package/dist/commands/chats/list.js +8 -9
  13. package/dist/commands/chats/unarchive.js +0 -1
  14. package/dist/commands/chats/update.js +0 -1
  15. package/dist/commands/commands.js +5 -12
  16. package/dist/commands/common/custom-properties.js +0 -1
  17. package/dist/commands/common/get-exports.js +0 -1
  18. package/dist/commands/common/request-export.js +0 -1
  19. package/dist/commands/common/uploads.js +0 -1
  20. package/dist/commands/group-tags/create.js +0 -1
  21. package/dist/commands/group-tags/delete.js +0 -1
  22. package/dist/commands/group-tags/get.js +0 -1
  23. package/dist/commands/group-tags/list-users.js +0 -1
  24. package/dist/commands/group-tags/list.js +0 -1
  25. package/dist/commands/group-tags/update.js +0 -1
  26. package/dist/commands/link-previews/add.js +0 -1
  27. package/dist/commands/members/add-group-tags.js +0 -1
  28. package/dist/commands/members/add.js +0 -1
  29. package/dist/commands/members/leave.js +0 -1
  30. package/dist/commands/members/list.js +0 -1
  31. package/dist/commands/members/remove-group-tag.js +0 -1
  32. package/dist/commands/members/remove.js +0 -1
  33. package/dist/commands/members/update.js +0 -1
  34. package/dist/commands/messages/create.js +9 -4
  35. package/dist/commands/messages/delete.js +0 -1
  36. package/dist/commands/messages/get.js +0 -1
  37. package/dist/commands/messages/list.js +9 -5
  38. package/dist/commands/messages/pin.js +0 -1
  39. package/dist/commands/messages/unpin.js +0 -1
  40. package/dist/commands/messages/update.js +0 -1
  41. package/dist/commands/profile/delete-status.js +0 -1
  42. package/dist/commands/profile/get-status.js +0 -1
  43. package/dist/commands/profile/get.js +0 -1
  44. package/dist/commands/profile/update-status.js +0 -1
  45. package/dist/commands/reactions/add.js +0 -1
  46. package/dist/commands/reactions/list.js +0 -1
  47. package/dist/commands/reactions/remove.js +0 -1
  48. package/dist/commands/read-member/list-readers.js +0 -1
  49. package/dist/commands/search/list-chats.js +0 -1
  50. package/dist/commands/search/list-messages.js +0 -1
  51. package/dist/commands/search/list-users.js +0 -1
  52. package/dist/commands/security/list.js +0 -30
  53. package/dist/commands/tasks/create.js +0 -1
  54. package/dist/commands/tasks/delete.js +0 -1
  55. package/dist/commands/tasks/get.js +0 -1
  56. package/dist/commands/tasks/list.js +0 -1
  57. package/dist/commands/tasks/update.js +0 -1
  58. package/dist/commands/threads/add.js +0 -1
  59. package/dist/commands/threads/get.js +0 -1
  60. package/dist/commands/upload.js +0 -1
  61. package/dist/commands/users/create.js +0 -1
  62. package/dist/commands/users/delete.js +0 -1
  63. package/dist/commands/users/get-status.js +0 -1
  64. package/dist/commands/users/get.js +0 -1
  65. package/dist/commands/users/list.js +0 -1
  66. package/dist/commands/users/remove-status.js +0 -1
  67. package/dist/commands/users/update-status.js +0 -1
  68. package/dist/commands/users/update.js +0 -1
  69. package/dist/commands/views/open.js +0 -1
  70. package/dist/data/changelog.json +42 -0
  71. package/dist/hooks/init.js +1 -20
  72. package/dist/profiles.js +0 -8
  73. package/oclif.manifest.json +1 -12709
  74. package/package.json +1 -1
  75. package/dist/commands/auth/refresh.js +0 -67
@@ -33,7 +33,6 @@ export default class ReactionsList extends BaseCommand {
33
33
  async run() {
34
34
  const { args, flags } = await this.parse(ReactionsList);
35
35
  this.parsedFlags = flags;
36
- this.checkScope("reactions:read");
37
36
  if (flags.all) {
38
37
  // Auto-pagination
39
38
  const allData = [];
@@ -70,7 +70,6 @@ export default class ReactionsRemove extends BaseCommand {
70
70
  this.exit(0);
71
71
  }
72
72
  }
73
- this.checkScope("reactions:write");
74
73
  const { data } = await this.apiRequest({
75
74
  method: 'DELETE',
76
75
  path: `/messages/${args.id}/reactions`,
@@ -31,7 +31,6 @@ export default class ReadMemberListReaders extends BaseCommand {
31
31
  async run() {
32
32
  const { args, flags } = await this.parse(ReadMemberListReaders);
33
33
  this.parsedFlags = flags;
34
- this.checkScope("messages:read");
35
34
  if (flags.all) {
36
35
  // Auto-pagination
37
36
  const allData = [];
@@ -53,7 +53,6 @@ export default class SearchListChats extends BaseCommand {
53
53
  async run() {
54
54
  const { args, flags } = await this.parse(SearchListChats);
55
55
  this.parsedFlags = flags;
56
- this.checkScope("search:chats");
57
56
  if (flags.all) {
58
57
  // Auto-pagination
59
58
  const allData = [];
@@ -50,7 +50,6 @@ export default class SearchListMessages extends BaseCommand {
50
50
  async run() {
51
51
  const { args, flags } = await this.parse(SearchListMessages);
52
52
  this.parsedFlags = flags;
53
- this.checkScope("search:messages");
54
53
  if (flags.all) {
55
54
  // Auto-pagination
56
55
  const allData = [];
@@ -49,7 +49,6 @@ export default class SearchListUsers extends BaseCommand {
49
49
  async run() {
50
50
  const { args, flags } = await this.parse(SearchListUsers);
51
51
  this.parsedFlags = flags;
52
- this.checkScope("search:users");
53
52
  if (flags.all) {
54
53
  // Auto-pagination
55
54
  const allData = [];
@@ -1,7 +1,6 @@
1
1
  // Auto-generated from openapi.yaml — DO NOT EDIT
2
2
  import { Flags } from '@oclif/core';
3
3
  import { BaseCommand } from '../../base-command.js';
4
- import * as clack from '@clack/prompts';
5
4
  export default class SecurityList extends BaseCommand {
6
5
  static description = "Журнал аудита событий";
7
6
  static examples = [
@@ -14,7 +13,6 @@ export default class SecurityList extends BaseCommand {
14
13
  static apiMethod = "GET";
15
14
  static apiPath = "/audit_events";
16
15
  static defaultColumns = ["id", "created_at", "event_key", "entity_id", "entity_type"];
17
- static requiredFlags = ["start-time", "end-time"];
18
16
  static args = {};
19
17
  static flags = {
20
18
  ...BaseCommand.baseFlags,
@@ -54,34 +52,6 @@ export default class SecurityList extends BaseCommand {
54
52
  async run() {
55
53
  const { args, flags } = await this.parse(SecurityList);
56
54
  this.parsedFlags = flags;
57
- const missingRequired = [
58
- { flag: 'start-time', label: "Начальная метка времени (включительно)", type: 'string' },
59
- { flag: 'end-time', label: "Конечная метка времени (исключительно)", type: 'string' },
60
- ].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
61
- if (missingRequired.length > 0) {
62
- if (this.isInteractive()) {
63
- for (const field of missingRequired) {
64
- const value = await clack.text({ message: field.label, validate: (v) => v.length === 0 ? 'Обязательное поле' : undefined });
65
- if (clack.isCancel(value)) {
66
- process.stderr.write('Отменено.\n');
67
- this.exit(0);
68
- }
69
- if (field.type === 'integer') {
70
- flags[field.flag] = Number.parseInt(value, 10);
71
- }
72
- else if (field.type === 'boolean') {
73
- flags[field.flag] = value === 'true';
74
- }
75
- else {
76
- flags[field.flag] = value;
77
- }
78
- }
79
- }
80
- else {
81
- this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --start-time <string>, --end-time <string>. pachca introspect security list" });
82
- }
83
- }
84
- this.checkScope("audit_events:read");
85
55
  if (flags.all) {
86
56
  // Auto-pagination
87
57
  const allData = [];
@@ -80,7 +80,6 @@ export default class TasksCreate extends BaseCommand {
80
80
  this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --kind <string>. pachca introspect tasks create" });
81
81
  }
82
82
  }
83
- this.checkScope("tasks:create");
84
83
  const body = { task: {
85
84
  kind: flags['kind'],
86
85
  content: flags['content'],
@@ -38,7 +38,6 @@ export default class TasksDelete extends BaseCommand {
38
38
  this.exit(0);
39
39
  }
40
40
  }
41
- this.checkScope("tasks:delete");
42
41
  const { data } = await this.apiRequest({
43
42
  method: 'DELETE',
44
43
  path: `/tasks/${args.id}`,
@@ -24,7 +24,6 @@ export default class TasksGet extends BaseCommand {
24
24
  async run() {
25
25
  const { args, flags } = await this.parse(TasksGet);
26
26
  this.parsedFlags = flags;
27
- this.checkScope("tasks:read");
28
27
  const { data } = await this.apiRequest({
29
28
  method: 'GET',
30
29
  path: `/tasks/${args.id}`,
@@ -29,7 +29,6 @@ export default class TasksList extends BaseCommand {
29
29
  async run() {
30
30
  const { args, flags } = await this.parse(TasksList);
31
31
  this.parsedFlags = flags;
32
- this.checkScope("tasks:read");
33
32
  if (flags.all) {
34
33
  // Auto-pagination
35
34
  const allData = [];
@@ -60,7 +60,6 @@ export default class TasksUpdate extends BaseCommand {
60
60
  }
61
61
  flags['content'] = Buffer.concat(chunks).toString('utf-8').trimEnd();
62
62
  }
63
- this.checkScope("tasks:update");
64
63
  const body = { task: {
65
64
  kind: flags['kind'],
66
65
  content: flags['content'],
@@ -23,7 +23,6 @@ export default class ThreadsAdd extends BaseCommand {
23
23
  async run() {
24
24
  const { args, flags } = await this.parse(ThreadsAdd);
25
25
  this.parsedFlags = flags;
26
- this.checkScope("threads:create");
27
26
  const { data } = await this.apiRequest({
28
27
  method: 'POST',
29
28
  path: `/messages/${args.id}/thread`,
@@ -19,7 +19,6 @@ export default class ThreadsGet extends BaseCommand {
19
19
  async run() {
20
20
  const { args, flags } = await this.parse(ThreadsGet);
21
21
  this.parsedFlags = flags;
22
- this.checkScope("threads:read");
23
22
  const { data } = await this.apiRequest({
24
23
  method: 'GET',
25
24
  path: `/threads/${args.id}`,
@@ -21,7 +21,6 @@ export default class Upload extends BaseCommand {
21
21
  async run() {
22
22
  const { args, flags } = await this.parse(Upload);
23
23
  this.parsedFlags = flags;
24
- this.checkScope('uploads:write');
25
24
  // Step 1: Get upload params
26
25
  const { data: uploadData } = await this.apiRequest({
27
26
  method: 'POST',
@@ -85,7 +85,6 @@ export default class UsersCreate extends BaseCommand {
85
85
  this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --email <string>. pachca introspect users create" });
86
86
  }
87
87
  }
88
- this.checkScope("users:create");
89
88
  const body = {
90
89
  user: {
91
90
  first_name: flags['first-name'],
@@ -38,7 +38,6 @@ export default class UsersDelete extends BaseCommand {
38
38
  this.exit(0);
39
39
  }
40
40
  }
41
- this.checkScope("users:delete");
42
41
  const { data } = await this.apiRequest({
43
42
  method: 'DELETE',
44
43
  path: `/users/${args.id}`,
@@ -24,7 +24,6 @@ export default class UsersGetStatus extends BaseCommand {
24
24
  async run() {
25
25
  const { args, flags } = await this.parse(UsersGetStatus);
26
26
  this.parsedFlags = flags;
27
- this.checkScope("user_status:read");
28
27
  const { data } = await this.apiRequest({
29
28
  method: 'GET',
30
29
  path: `/users/${args.user_id}/status`,
@@ -24,7 +24,6 @@ export default class UsersGet extends BaseCommand {
24
24
  async run() {
25
25
  const { args, flags } = await this.parse(UsersGet);
26
26
  this.parsedFlags = flags;
27
- this.checkScope("users:read");
28
27
  const { data } = await this.apiRequest({
29
28
  method: 'GET',
30
29
  path: `/users/${args.id}`,
@@ -32,7 +32,6 @@ export default class UsersList extends BaseCommand {
32
32
  async run() {
33
33
  const { args, flags } = await this.parse(UsersList);
34
34
  this.parsedFlags = flags;
35
- this.checkScope("users:read");
36
35
  if (flags.all) {
37
36
  // Auto-pagination
38
37
  const allData = [];
@@ -38,7 +38,6 @@ export default class UsersRemoveStatus extends BaseCommand {
38
38
  this.exit(0);
39
39
  }
40
40
  }
41
- this.checkScope("user_status:write");
42
41
  const { data } = await this.apiRequest({
43
42
  method: 'DELETE',
44
43
  path: `/users/${args.user_id}/status`,
@@ -76,7 +76,6 @@ export default class UsersUpdateStatus extends BaseCommand {
76
76
  if (validationErrors.length > 0) {
77
77
  this.validationError(validationErrors);
78
78
  }
79
- this.checkScope("user_status:write");
80
79
  const body = { status: {
81
80
  emoji: flags['emoji'],
82
81
  title: flags['title'],
@@ -58,7 +58,6 @@ export default class UsersUpdate extends BaseCommand {
58
58
  async run() {
59
59
  const { args, flags } = await this.parse(UsersUpdate);
60
60
  this.parsedFlags = flags;
61
- this.checkScope("users:update");
62
61
  const body = { user: {
63
62
  first_name: flags['first-name'],
64
63
  last_name: flags['last-name'],
@@ -96,7 +96,6 @@ export default class ViewsOpen extends BaseCommand {
96
96
  if (validationErrors.length > 0) {
97
97
  this.validationError(validationErrors);
98
98
  }
99
- this.checkScope("views:write");
100
99
  const body = {
101
100
  view: {
102
101
  title: flags['title'],
@@ -1,4 +1,46 @@
1
1
  [
2
+ {
3
+ "version": "2026.3.10",
4
+ "date": "21 марта 2026",
5
+ "changes": [
6
+ {
7
+ "type": "~",
8
+ "command": "messages create",
9
+ "description": "Поле link_preview перемещено на верхний уровень тела запроса (раньше было внутри message)"
10
+ },
11
+ {
12
+ "type": "~",
13
+ "command": "security list",
14
+ "description": "Параметры start-time и end-time стали необязательными"
15
+ },
16
+ {
17
+ "type": "~",
18
+ "command": "chats list, messages list",
19
+ "description": "Сортировка через --sort и --order вместо --sort-id и --sort-last-message-at"
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "version": "2026.3.9",
25
+ "date": "19 марта 2026",
26
+ "changes": [
27
+ {
28
+ "type": "~",
29
+ "command": "all",
30
+ "description": "Убрана клиентская валидация скоупов — проверка разрешений теперь только на стороне API (403)"
31
+ },
32
+ {
33
+ "type": "~",
34
+ "command": "auth login",
35
+ "description": "Профиль больше не сохраняет список скоупов — только тип, имя и email"
36
+ },
37
+ {
38
+ "type": "-",
39
+ "command": "auth refresh",
40
+ "description": "Команда удалена — кеширование скоупов больше не используется"
41
+ }
42
+ ]
43
+ },
2
44
  {
3
45
  "version": "2026.3.8",
4
46
  "date": "17 марта 2026",
@@ -4,8 +4,7 @@ import { fileURLToPath } from 'node:url';
4
4
  import { spawn } from 'node:child_process';
5
5
  import semver from 'semver';
6
6
  import ansis from 'ansis';
7
- import { setProfile, getDefaults, resolveToken, TokenNotFoundError, ProfileNotFoundError, } from '../profiles.js';
8
- import { request } from '../client.js';
7
+ import { getDefaults, resolveToken, TokenNotFoundError, ProfileNotFoundError, } from '../profiles.js';
9
8
  import { outputError } from '../output.js';
10
9
  import { defaultOutputFormat, isInteractive } from '../utils.js';
11
10
  /**
@@ -131,24 +130,6 @@ const hook = async function (opts) {
131
130
  // Verify auth exists
132
131
  try {
133
132
  const { profileName, profile } = resolveToken({ token: argvToken, profile: argvProfile });
134
- // Refresh bot scopes if stale (>24h)
135
- if (profileName && profile?.type === 'bot' && profile.scopes_refreshed_at) {
136
- const refreshedAt = new Date(profile.scopes_refreshed_at).getTime();
137
- const now = Date.now();
138
- const twentyFourHours = 24 * 60 * 60 * 1000;
139
- if (now - refreshedAt > twentyFourHours) {
140
- try {
141
- const response = await request({ method: 'GET', path: '/oauth/token/info', token: profile.token }, { quiet: true });
142
- const wrapper = response.data;
143
- profile.scopes = wrapper.data.scopes || [];
144
- profile.scopes_refreshed_at = new Date().toISOString();
145
- setProfile(profileName, profile);
146
- }
147
- catch {
148
- // Silently ignore refresh errors — use cached scopes
149
- }
150
- }
151
- }
152
133
  }
153
134
  catch (error) {
154
135
  if (error instanceof TokenNotFoundError) {
package/dist/profiles.js CHANGED
@@ -171,14 +171,6 @@ export function getConfigFilePermissions() {
171
171
  const stat = fs.statSync(configPath);
172
172
  return (stat.mode & 0o777).toString(8);
173
173
  }
174
- export function invalidateScopes(profileName) {
175
- const config = readConfig();
176
- if (config.profiles?.[profileName]) {
177
- config.profiles[profileName].scopes = [];
178
- config.profiles[profileName].scopes_refreshed_at = undefined;
179
- writeConfig(config);
180
- }
181
- }
182
174
  export class TokenNotFoundError extends Error {
183
175
  constructor() {
184
176
  super('Token not found');