ktalk-cli 2.0.0__tar.gz → 3.0.0__tar.gz

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 (122) hide show
  1. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/.gitignore +4 -0
  2. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/PKG-INFO +109 -99
  3. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/README.md +108 -98
  4. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/pyproject.toml +1 -1
  5. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/auth.py +20 -71
  6. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/calendar_reader.py +2 -2
  7. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli.py +15 -1
  8. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_content.py +36 -17
  9. ktalk_cli-3.0.0/src/ktalk_cli/cli_doctor.py +147 -0
  10. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_sync.py +11 -26
  11. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_token.py +4 -9
  12. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/client.py +44 -123
  13. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/config.py +61 -46
  14. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/contacts.py +2 -2
  15. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/download.py +6 -30
  16. ktalk_cli-3.0.0/src/ktalk_cli/endpoints.py +84 -0
  17. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/formatters.py +42 -8
  18. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/host_config.py +4 -0
  19. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/meeting_body.py +40 -23
  20. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/meeting_scheduling.py +2 -2
  21. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/pagination.py +0 -15
  22. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/rooms.py +4 -4
  23. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/token_file.py +14 -0
  24. ktalk_cli-3.0.0/tests/test_auth_modes.py +84 -0
  25. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_calendar.py +3 -24
  26. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_content.py +11 -7
  27. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_config.py +5 -5
  28. ktalk_cli-3.0.0/tests/test_diagnostics.py +111 -0
  29. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_download.py +7 -56
  30. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_formatters.py +67 -0
  31. ktalk_cli-3.0.0/tests/test_fr42_single_credential_source.py +114 -0
  32. ktalk_cli-3.0.0/tests/test_fr43_legacy_key_removal_warning.py +151 -0
  33. ktalk_cli-3.0.0/tests/test_fr44_auth_status_accepted_rejected.py +132 -0
  34. ktalk_cli-3.0.0/tests/test_fr47_missing_fields_completeness.py +146 -0
  35. ktalk_cli-3.0.0/tests/test_fr48_doctor_summary_diagnostics.py +421 -0
  36. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_meeting_cancel.py +6 -28
  37. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_meeting_scheduling.py +2 -24
  38. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_nfr17_identity_verification.py +294 -20
  39. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_pagination.py +5 -16
  40. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_reconciliation.py +16 -16
  41. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_rooms.py +2 -22
  42. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_search_contacts.py +6 -39
  43. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_secret_masking.py +26 -16
  44. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_token_file.py +1 -16
  45. ktalk_cli-2.0.0/src/ktalk_cli/endpoints.py +0 -145
  46. ktalk_cli-2.0.0/tests/test_auth_modes.py +0 -243
  47. ktalk_cli-2.0.0/tests/test_diagnostics.py +0 -224
  48. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/LICENSE +0 -0
  49. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/CLAUDE.md +0 -0
  50. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/__init__.py +0 -0
  51. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_contacts.py +0 -0
  52. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_meeting.py +0 -0
  53. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_meeting_args.py +0 -0
  54. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_meeting_confirm.py +0 -0
  55. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_meetings_read.py +0 -0
  56. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_sanction.py +0 -0
  57. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/cli_store.py +0 -0
  58. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/confirmation.py +0 -0
  59. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/contour_diagnostics.py +0 -0
  60. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/enrichment.py +0 -0
  61. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/meeting_cancel.py +0 -0
  62. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/reconciliation.py +0 -0
  63. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/registry.py +0 -0
  64. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/store.py +0 -0
  65. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/store_migration.py +0 -0
  66. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/transcript_identity.py +0 -0
  67. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/write_journal.py +0 -0
  68. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/src/ktalk_cli/write_sanction.py +0 -0
  69. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/conftest.py +0 -0
  70. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/access-info-expired.json +0 -0
  71. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/access-info-full.json +0 -0
  72. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/archive-8col.md +0 -0
  73. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/archive-dup-id.md +0 -0
  74. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/archive-escaped-pipe-7col.md +0 -0
  75. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/archive-page1.json +0 -0
  76. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/archive-page2-empty.json +0 -0
  77. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/archive-pipe-in-name.md +0 -0
  78. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/calendar-item-session.json +0 -0
  79. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/chat-messages-session.json +0 -0
  80. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/conference-history-session-oversized.json +0 -0
  81. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/conference-history-session.json +0 -0
  82. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/error-body-problem-json.json +0 -0
  83. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/error-body-validation.json +0 -0
  84. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/recording-detail-session-full-participants.json +0 -0
  85. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/recording-detail-session-oversized-partial.json +0 -0
  86. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/recording-detail-with-qualities.json +0 -0
  87. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/recording-list-item-session.json +0 -0
  88. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/recordings-list-apikey-page1.json +0 -0
  89. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/recordings-list-apikey-page2.json +0 -0
  90. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/registry-archive-2026-04.md +0 -0
  91. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/registry.md +0 -0
  92. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/fixtures/room-detail-session.json +0 -0
  93. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_adr022_ktalk_cli_rename.py +0 -0
  94. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_archive.py +0 -0
  95. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_chat.py +0 -0
  96. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli.py +0 -0
  97. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_config_show.py +0 -0
  98. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_export_store_isolation.py +0 -0
  99. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_host_config_wiring.py +0 -0
  100. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_meeting.py +0 -0
  101. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_meeting_sanctioned.py +0 -0
  102. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_meetings_surface.py +0 -0
  103. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_cli_migrate_to_central_store.py +0 -0
  104. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_client.py +0 -0
  105. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_concurrency.py +0 -0
  106. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_confirmation.py +0 -0
  107. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_contour_diagnostics.py +0 -0
  108. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_enrichment.py +0 -0
  109. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_fr19_auth_status.py +0 -0
  110. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_fr21_no_vault_layout.py +0 -0
  111. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_fr39_calendar_inclusive_end.py +0 -0
  112. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_fr40_timezone_format.py +0 -0
  113. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_fr41_last_synced.py +0 -0
  114. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_host_config.py +0 -0
  115. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_issue3_null_id_fallback.py +0 -0
  116. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_meeting_body.py +0 -0
  117. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_migration.py +0 -0
  118. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_registry.py +0 -0
  119. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_store.py +0 -0
  120. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_store_migration.py +0 -0
  121. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_write_journal.py +0 -0
  122. {ktalk_cli-2.0.0 → ktalk_cli-3.0.0}/tests/test_write_sanction.py +0 -0
@@ -25,5 +25,9 @@ docs/*.har
25
25
  *.db
26
26
  .beads-credential-key
27
27
  .beads/proxieddb/
28
+ # Аудиторский сайдкар взаимодействий агентов (bd, audit.enabled) — локальная
29
+ # телеметрия прогона, не состояние трекера: оно живёт в Dolt и уезжает через
30
+ # refs/dolt/data (sync.remote в .beads/config.yaml), а не через этот файл.
31
+ .beads/interactions.jsonl
28
32
  *.gate.lock*
29
33
  packaging/*/dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ktalk-cli
3
- Version: 2.0.0
3
+ Version: 3.0.0
4
4
  Summary: CLI for accessing Kontur Talk (KTalk) recordings, transcripts and summaries
5
5
  Project-URL: Homepage, https://github.com/mdemyanov/ktalk-cli
6
6
  Project-URL: Repository, https://github.com/mdemyanov/ktalk-cli
@@ -26,15 +26,18 @@ Description-Content-Type: text/markdown
26
26
  [![PyPI](https://img.shields.io/pypi/v/ktalk-cli)](https://pypi.org/project/ktalk-cli/)
27
27
  [![Python](https://img.shields.io/pypi/pyversions/ktalk-cli)](https://pypi.org/project/ktalk-cli/)
28
28
 
29
- CLI `ktalk` для доступа к записям [Контур.Толк](https://ktalk.ru) (KTalk) — чтение
30
- записей, транскриптов и саммари, работа с расписанием, операционный реестр
31
- обработки записей на SQLite.
29
+ CLI `ktalk` — интерфейс командной строки для тех, кто работает с записями видеовстреч
30
+ [Контур.Толк](https://ktalk.ru) (KTalk) программно: читает записи, транскрипты и саммари,
31
+ управляет расписанием, ведёт локальный реестр обработки записей на SQLite. Годится и как
32
+ самостоятельный инструмент, и как предусловие плагина Claude Code `ktalk` — подробнее в
33
+ разделе «Пакет и плагин Claude Code» ниже.
32
34
 
33
35
  > Раньше пакет назывался `ktalk-mcp` и, помимо CLI, поднимал MCP-сервер для
34
36
  > Claude Code (инструменты вида `ktalk_list_recordings`). Этот слой снят
35
37
  > целиком — MCP в пакете больше нет, единственная точка входа — команда
36
- > `ktalk`. Нужна интеграция с Claude Code — отдельный плагин `ktalk` вызывает
37
- > эту же CLI напрямую, без MCP-сервера.
38
+ > `ktalk`. Пришли по старой ссылке или ищете `ktalk-mcp` — это тот же проект
39
+ > под новым именем, старый пакет дальше не развивается (о конфликте имени
40
+ > команды при апгрейде — ниже, в «Установке»).
38
41
 
39
42
  Умеет:
40
43
  - Список записей конференций и детали одной записи.
@@ -42,11 +45,11 @@ CLI `ktalk` для доступа к записям [Контур.Толк](http
42
45
  - Саммари и протоколы встреч.
43
46
  - Полный состав участников записи (обходит лимит в 6 из списковых ответов).
44
47
  - Скачивание видеофайла записи.
45
- - Архив встреч и историю чата (только с персональным API-ключом).
46
- - Конфигурацию комнаты и календарь запланированных встреч (только с session token).
48
+ - Историю чата встречи.
49
+ - Конфигурацию комнаты и календарь запланированных встреч.
47
50
  - Предпросмотр и создание новой встречи — создание требует интерактивного
48
51
  терминала и явного подтверждения, см. «Планирование встречи» ниже.
49
- - Диагностику авторизации — какой ключ/токен активен и почему запрос не проходит.
52
+ - Диагностику авторизации — жив ли токен и почему запрос не проходит.
50
53
  - Операционный реестр обработки записей на SQLite — синхронизация, статусы,
51
54
  markdown-зеркало для git, см. «Реестр записей» ниже.
52
55
 
@@ -73,22 +76,41 @@ uv tool uninstall ktalk-mcp
73
76
  uv tool install ktalk-cli
74
77
  ```
75
78
 
79
+ **Проверка версии** — после установки или обновления:
80
+
81
+ ```bash
82
+ ktalk --version # печатает, например: ktalk-cli 2.1.0
83
+ ```
84
+
85
+ **Обновление** до последней версии — та же команда `install`, только `upgrade`:
86
+
87
+ ```bash
88
+ uv tool upgrade ktalk-cli
89
+ ```
90
+
76
91
  ## Авторизация
77
92
 
78
- CLI поддерживает два способа авторизации: session token (кука браузера) и
79
- персональный API-ключ. Способы исключают друг друга: если задать обе переменные,
80
- побеждает `KTALK_PERSONAL_API_KEY` — `KTALK_SESSION_TOKEN` в этом случае вообще не
81
- читается. Не задать ни один — команда завершится понятной ошибкой.
93
+ **С версии 3.0.0 CLI работает только через session token** (кука браузера) — режим
94
+ персонального API-ключа (`KTALK_PERSONAL_API_KEY`) снят целиком (ADR-025): он
95
+ конкурировал с сессией молча (при обеих заданных переменных побеждал ключ без
96
+ объяснения в тексте отказа) и диагностика `auth-status` объявляла заведомо
97
+ невалидный ключ «валидным» на 403.
98
+
99
+ **Цена снятия для тех, кто держал постоянный ключ:** персональный ключ не протухал
100
+ без предупреждения, session token — протухает. Постоянная работа теперь требует
101
+ ручного обновления токена по мере его протухания (`ktalk token set -`, см. ниже) —
102
+ это не восстанавливается автоматически снятием ключа.
82
103
 
83
- Персональный API-ключ не привязан к браузерной сессии и не протухает без предупреждения,
84
- в отличие от session token. Берите его, если нужна стабильная работа без ручного
85
- обновления, а не только разовый запрос.
104
+ Переменная `KTALK_PERSONAL_API_KEY`, если она всё ещё задана в окружении, не
105
+ читается как credential ни на одном шаге — CLI печатает об этом одно предупреждение
106
+ на stderr при каждом вызове и продолжает работу на сессионном токене.
86
107
 
87
108
  ### Session token
88
109
 
89
- Session token — токен вашей браузерной сессии Толка. Быстрый способ начать, но
90
- токен живёт недолго и протухает без предупреждения — при регулярном
91
- использовании удобнее персональный API-ключ (ниже).
110
+ Session token — токен вашей браузерной сессии Толка. Единственный поддерживаемый
111
+ источник credential (ADR-025). Живёт недолго и протухает без предупреждения — при
112
+ регулярной работе повторяйте те же два шага ниже, когда команда начнёт отказывать
113
+ кодом авторизации.
92
114
 
93
115
  **Два шага.** На вкладке, где вы залогинены в `https://your-domain.ktalk.ru`, откройте
94
116
  DevTools (`F12`, или `Cmd+Option+I` на Mac) → **Console** и выполните:
@@ -118,9 +140,11 @@ ktalk auth-status # жива ли авторизация — реальны
118
140
 
119
141
  | # | Источник | Комментарий |
120
142
  |---|---|---|
121
- | 1 | `KTALK_PERSONAL_API_KEY` | режим персонального ключа, сессия дальше не читается |
122
- | 2 | `KTALK_SESSION_TOKEN` (окружение или `.env` в рабочей директории) | заданное явно сильнее лежащего на диске |
123
- | 3 | `~/.config/ktalk-mcp/token` | дефолтный путь для повседневной работы |
143
+ | 1 | `KTALK_SESSION_TOKEN` (окружение или `.env` в рабочей директории) | заданное явно сильнее лежащего на диске |
144
+ | 2 | `~/.config/ktalk-mcp/token` | дефолтный путь для повседневной работы |
145
+
146
+ Ни один запрос не несёт заголовок `X-Auth-Token` — единственный транспорт credential
147
+ теперь query-параметр `sessionToken`.
124
148
 
125
149
  > Путь `~/.config/ktalk-mcp/token` не переименован вместе с пакетом и остаётся
126
150
  > таким намеренно: он выбран независимо от имени дистрибутива (каталог
@@ -141,57 +165,20 @@ ktalk auth-status # жива ли авторизация — реальны
141
165
  > ошибку авторизации, повторите те же два шага — `ktalk token set -` перезаписывает
142
166
  > файл, права переставлять не нужно.
143
167
 
144
- ### Персональный API-ключ
145
-
146
- Персональный API-ключ выдаётся в админке Толка на конкретного пользователя на
147
- настраиваемый срок и не зависит от того, открыт ли браузер. Передаётся заголовком
148
- `X-Auth-Token`, а не в URL — секрет не попадает в query-параметры и логи веб-сервера.
149
-
150
- Выпускается и ротируется в разделе **Управление → API-ключи** админки Толка (UI-шаг,
151
- CLI-эквивалента нет; экранные шаги здесь не расписываем — актуальный порядок действий
152
- смотрите в справке Контура:
153
- [«Персональный API-ключ доступа в Толке»](https://support.kontur.ru/talk/86797)).
154
- Значение ключа показывается один раз в течение часа после создания — не скопировали
155
- вовремя, придётся выпускать новый.
156
-
157
- **Не путайте с ключом пространства.** В Толке есть второй, отдельный ключ —
158
- пространственный, с заголовком `X-API-Key`, выдаётся не на пользователя, а на всё
159
- пространство целиком. `ktalk-cli` работает только с персональным ключом
160
- (`X-Auth-Token`); ключ пространства не поддерживается — переменная называется
161
- `KTALK_PERSONAL_API_KEY`, а не `KTALK_API_KEY`, намеренно, чтобы их не перепутать.
162
-
163
- При выпуске ключа в админке выбираются права (scope). Не хватает прав — запрос вернёт
164
- 403, и по виду это неотличимо от «ключ невалиден», хотя ключ рабочий (подробнее —
165
- «Диагностика авторизации» ниже).
166
-
167
- | Право (scope) | Даёт доступ к |
168
- |---|---|
169
- | `application.recording.read` | Список записей, детали, транскрипт, саммари, скачивание файла, участники |
170
- | `application.reporting.read` | Архив встреч, чат встречи, отчёты по участникам |
171
- | `application.applications.read` | Опционально. Без него `ktalk auth-status` не покажет состав прав и срок действия ключа — только «ключ живой / не живой» |
172
-
173
- > **Если реестр `ktalk` уже накопил записи в session-режиме,** перед первым `ktalk sync`
174
- > после переключения на персональный ключ обязательно выполните `ktalk sync --dry-run`.
175
- > Внутренний и официальный контуры API отдают идентификаторы записей по-разному, и без
176
- > сверки первый боевой sync под ключом рискует задвоить весь реестр. Команда только
177
- > сверяет id и ничего не пишет — см. таблицу команд реестра ниже.
178
-
179
168
  ### Переменные окружения
180
169
 
181
170
  ```bash
182
- export KTALK_PERSONAL_API_KEY="ваш_персональный_api_ключ"
183
- # или
184
171
  export KTALK_SESSION_TOKEN="ваш_session_token"
185
172
  export KTALK_BASE_URL="https://your-domain.ktalk.ru"
186
173
  ```
187
174
 
188
- Для session-режима переменная не обязательна: без неё читается файл
189
- `~/.config/ktalk-mcp/token` (см. «Session token»).
175
+ Переменная не обязательна: без неё читается файл `~/.config/ktalk-mcp/token`
176
+ (см. «Session token»).
190
177
 
191
178
  Также поддерживается файл `.env` в рабочей директории:
192
179
 
193
180
  ```env
194
- KTALK_PERSONAL_API_KEY=ваш_персональный_api_ключ
181
+ KTALK_SESSION_TOKEN=ваш_session_token
195
182
  KTALK_BASE_URL=https://your-domain.ktalk.ru
196
183
  ```
197
184
 
@@ -206,35 +193,45 @@ ktalk auth-status
206
193
  Диагностика различает два случая, которые снаружи выглядят одинаково — просто ошибка, —
207
194
  но чинятся по-разному:
208
195
 
209
- - **401** — ключ или токен невалиден либо истёк. Перевыпустите его.
210
- - **403** — ключ рабочий, но конкретному запросу не хватает прав (scope). Отредактируйте
211
- права ключа в админке Толка (см. таблицу в разделе «Персональный API-ключ» выше) —
212
- перевыпускать ключ не нужно.
196
+ - **401** — токен невалиден либо истёк. Обновите его: `ktalk token set -` (или
197
+ переменную `KTALK_SESSION_TOKEN`, если она задана).
198
+ - **403** — токен рабочий, но у текущей сессии нет прав на эту операцию.
199
+ Перевыпускать токен не нужно.
213
200
 
214
- У session token понятия scope нет — диагностика в этом режиме пробным запросом списка
215
- записей сообщает только «токен работает / не работает», без прав и срока действия.
201
+ У session token понятия scope и срока действия нет — диагностика выполняет реальный
202
+ пробный запрос (список записей), а не имитацию без сети.
216
203
 
217
- Режим ключа не проверен полностью на боевом окружении — команда описывает задуманное
218
- поведение, а не гарантию для любого ключа.
204
+ `--json`-ответ — `{"alive": bool, "note": str | None}`. Отказ пробного запроса виден
205
+ по обоим каналам сразу: поле `alive: false` в теле ответа И ненулевой код возврата
206
+ процесса — полагаться только на один из двух нельзя.
219
207
 
220
208
  ## Команды чтения записей и справочников
221
209
 
222
210
  Все команды поддерживают `--json` (валидный JSON в stdout; ошибки — в stderr с
223
211
  ненулевым кодом возврата).
224
212
 
213
+ ### Коды возврата
214
+
215
+ | Код | Значение |
216
+ |---|---|
217
+ | `0` | Успех. |
218
+ | `1` | Отказ вызова — сеть, сервер, конфигурация. |
219
+ | `2` | Usage error — неверные аргументы CLI (`argparse`). |
220
+ | `3` | Только `ktalk get-transcript`. Данные получены и напечатаны полностью, но независимая сверка идентичности не сошлась (`identity_check.result == "mismatch"`) — состав участников транскрипта разошёлся с составом записи. Это не сбой команды: код 3 отличает «данные есть, но сверка не сошлась» от `0` (сошлось или не проверялось) и от `1`/`2` (данных нет вовсе). Подробности — в самом теле ответа, поле `identity_check` (ADR-024 §Д1). |
221
+
225
222
  | Команда | Назначение |
226
223
  |---|---|
227
224
  | `ktalk list-recordings [--query Q] [--start-from ISO] [--start-to ISO] [--top N] [--order O] [--page-token T]` | Список записей. `--top` 1–1000 (по умолчанию 30); `--order`: `byTimeNewFirst` (умолчание), `byTimeOldFirst`, `byTitle`, `bySizeBigFirst`, `bySizeSmallFirst`. |
228
225
  | `ktalk get-recording <recording_key>` | Детали записи — автор, дата, длительность, участники (список ограничен 6, полный состав — `get-participants`). |
229
- | `ktalk get-transcript <recording_key> [--chunk N] [--chunk-size N]` | Транскрипт по спикерам с таймкодами. Длинный транскрипт режется на чанки по границам реплик: `--chunk 0` (умолчание) — целиком или первый чанк; `--chunk-size` — макс. символов в чанке (умолчание 30000, ~7500 токенов). |
226
+ | `ktalk get-transcript <recording_key> [--chunk N] [--chunk-size N]` | Транскрипт по спикерам с таймкодами. Длинный транскрипт режется на чанки по границам реплик: `--chunk 0` (умолчание) — целиком или первый чанк; `--chunk-size` — макс. символов в чанке (умолчание 30000, ~7500 токенов). Независимая сверка идентичности включена по умолчанию (`--no-verify-identity` отключает); `--chunk` вне диапазона сверку по сети не запускает вовсе, `identity_check.result == "not_checked"`/`reason: "chunk_out_of_range"`. |
230
227
  | `ktalk get-summary <recording_key>` | Полное саммари (краткое резюме + протокол). |
231
228
  | `ktalk get-summary-type <recording_key> --type shortSummary\|protocol` | Саммари одного типа. |
232
229
  | `ktalk get-participants <recording_key>` | Полный состав участников, включая анонимных — обходит лимит в 6, который отдают `get-recording`/`list-recordings`. |
233
230
  | `ktalk download-recording <recording_key> --target PATH [--quality Q]` | Скачивает видеофайл потоково, без буферизации в памяти. Существующий файл не перезаписывается; `--quality` не указано — берётся дефолт для записи (например `900p`). |
234
- | `ktalk list-archive --from ISO --to ISO [--room-name N]` | Архив встреч за период. Только режим персонального ключа (право `application.reporting.read`). Читает всё окно на клиенте, без постраничного чтения. |
235
- | `ktalk get-chat-messages [--recording-key K \| --conference-key K] [--channel C]` | Сообщения чата встречи; один из двух ключей обязателен. Только режим персонального ключа. Канал не указан — определяется автоматически. |
236
- | `ktalk get-room <room_name>` | Конфигурация комнаты — политики аудио/видео/демонстрации, модераторы, SIP, чат, маскирование. Только режим session token. **Побочный эффект:** если комнаты с таким именем ещё нет, она создаётся. |
237
- | `ktalk list-calendar --start ISO --end ISO [--room-name N]` | Встречи за окно дат, видимые активной авторизации — это не «ваш личный календарь», а всё, что видит текущая авторизация, включая чужие встречи. Только режим session token. Сервер лимитирует один запрос семью днями и сотней встреч на сегмент — команда сама режет произвольное окно на сегменты; при упоре в потолок ответ предупреждает о возможно неполной выдаче. |
231
+ | `ktalk list-archive --from ISO --to ISO [--room-name N]` | Архив встреч за период. **Недоступна** — архив никогда не имел рабочего пути под session token; команда отказывает до сети с явным сообщением на каждый вызов (ADR-025). |
232
+ | `ktalk get-chat-messages [--recording-key K \| --conference-key K] [--channel C]` | Сообщения чата встречи; один из двух ключей обязателен. Канал не указан — определяется автоматически. |
233
+ | `ktalk get-room <room_name>` | Конфигурация комнаты — политики аудио/видео/демонстрации, модераторы, SIP, чат, маскирование. **Побочный эффект:** если комнаты с таким именем ещё нет, она создаётся. |
234
+ | `ktalk list-calendar --start ISO --end ISO [--room-name N]` | Встречи за окно дат, видимые активной авторизации — это не «ваш личный календарь», а всё, что видит текущая авторизация, включая чужие встречи. Сервер лимитирует один запрос семью днями и сотней встреч на сегмент — команда сама режет произвольное окно на сегменты; при упоре в потолок ответ предупреждает о возможно неполной выдаче. |
238
235
 
239
236
  ## Планирование встречи
240
237
 
@@ -247,8 +244,8 @@ ktalk auth-status
247
244
  перед отправкой печатает предпросмотр и требует набрать слово `да`.
248
245
  - Предпросмотр без создания — `ktalk create-meeting-preview`, не делает ни
249
246
  одного сетевого запроса.
250
- - Обе команды работают только в режиме session token — в режиме персонального
251
- ключа создание встречи не подтверждено ни разу и потому отключено.
247
+ - Обе команды используют session token — единственный оставшийся режим
248
+ авторизации (ADR-025).
252
249
 
253
250
  **Ни одно поле не имеет значения по умолчанию** (кроме описания встречи — пустая
254
251
  строка, если не задано). Тема, начало, конец, часовой пояс, комната, участники,
@@ -302,33 +299,22 @@ ktalk create-meeting-confirm \
302
299
 
303
300
  ## API
304
301
 
305
- CLI работает с KTalk Web API. Набор путей, которые вызывает клиент, зависит от
306
- активного режима авторизации (см. «Авторизация» выше):
307
-
308
- - **Session-режим** — авторизация query-параметром `sessionToken`, используется
309
- внутренний контур API.
310
- - **Режим персонального ключа** — авторизация заголовком `X-Auth-Token`, используются
311
- официальные пути интеграторского API (`talk.public.api-api-2.json`).
312
-
313
- Транскрипт и саммари используют один и тот же путь в обоих режимах:
302
+ CLI работает с KTalk Web API через единственный (session token) режим авторизации
303
+ (см. «Авторизация» выше) — query-параметр `sessionToken`, внутренний недокументированный
304
+ контур API:
314
305
 
315
306
  | Эндпоинт | Описание |
316
307
  |----------|----------|
308
+ | `GET /api/recordings` | Список записей |
309
+ | `GET /api/recordings/{id}` | Детали записи |
317
310
  | `GET /api/recordings/{id}/transcript` | Транскрипт |
318
311
  | `GET /api/recordings/v2/{id}/summary` | Полное саммари (v2) |
319
312
  | `GET /api/recordings/{id}/summary/{type}` | Саммари по типу |
320
313
 
321
- Список записей и детали записи используют разные пути в session- и api-key-режимах.
322
- Архив встреч, чат, полный состав участников, скачивание файла и диагностика ключа
323
- доступны только в режиме персонального ключа (нужные права — в таблице раздела
324
- «Персональный API-ключ» выше).
314
+ Архив встреч (`list-archive`) недоступен: под session token у него нет и никогда не
315
+ было рабочего пути (ADR-025) — команда отказывает до сети с явным сообщением.
325
316
 
326
- Комната, календарь и создание встречи работают только в режиме session token — в
327
- режиме персонального ключа эти операции отказывают осознанно, а не по случайному
328
- пробелу: путь на api-key либо не подтверждён вовсе, либо ведёт себя необъяснимо
329
- непоследовательно при проверке.
330
-
331
- > OpenAPI спецификация `talk.public.api-api-2.json` включена как справочник, но содержит расхождения с реальным API (пути, формат авторизации, структура ответов).
317
+ > OpenAPI спецификация `talk.public.api-api-2.json` включена как справочник, но содержит расхождения с реальным API (пути, формат авторизации, структура ответов). Пути, достижимые только под снятым режимом персонального ключа (`X-Auth-Token`), больше не применимы к этому CLI.
332
318
 
333
319
  ## Реестр записей (`ktalk`)
334
320
 
@@ -351,10 +337,10 @@ CLI работает с KTalk Web API. Набор путей, которые в
351
337
 
352
338
  | Команда | Назначение |
353
339
  |---|---|
354
- | `ktalk sync [--days 7] [--json] [--dry-run]` | Загрузить записи из KTalk, upsert новых (`new`), экспирировать `new` старше N дней → `skipped`, показать дашборд. Идемпотентно. `--dry-run` — сверить id с реестром без записи, ничего не пишет (обязателен перед первым `sync` в режиме персонального ключа — см. «Персональный API-ключ»). |
340
+ | `ktalk sync [--days 7] [--json] [--dry-run]` | Загрузить записи из KTalk, upsert новых (`new`), экспирировать `new` старше N дней → `skipped`, показать дашборд. Идемпотентно. `--dry-run` — сверить id с реестром без записи, ничего не пишет. |
355
341
  | `ktalk token set <значение\|->` | Записать session-токен в `~/.config/ktalk-mcp/token` (`0600`). `-` — прочитать из stdin: `pbpaste \| ktalk token set -`. Значение не печатается. |
356
342
  | `ktalk token status [--json]` | Есть ли файл токена, его права и маска значения. |
357
- | `ktalk auth-status [--json]` | Диагностика активной авторизации — жив ли ключ/токен, какие права у ключа. См. «Диагностика авторизации». |
343
+ | `ktalk auth-status [--json]` | Диагностика активной авторизации — жив ли токен. См. «Диагностика авторизации». |
358
344
  | `ktalk dashboard [--json]` | Дашборд: новые записи, статистика по статусам. |
359
345
  | `ktalk list [--status S] [--json]` | Список записей с фильтром по статусу. |
360
346
  | `ktalk show <id> [--json]` | Детали записи: участники, статус, пути, длительность. |
@@ -382,10 +368,34 @@ uv run pytest -v
382
368
  # Линтинг
383
369
  uv run ruff check .
384
370
 
385
- # Локальный запуск CLI (session token или KTALK_PERSONAL_API_KEY — см. «Авторизация»)
371
+ # Локальный запуск CLI (session token — см. «Авторизация»)
386
372
  KTALK_SESSION_TOKEN=... KTALK_BASE_URL=... uv run ktalk auth-status
387
373
  ```
388
374
 
375
+ ## Пакет и плагин Claude Code
376
+
377
+ `ktalk-cli` работает и сам по себе, и как предусловие плагина Claude Code `ktalk`. Плагин не
378
+ обращается к KTalk напрямую и не поднимает MCP-сервер — он вызывает эту же команду `ktalk`
379
+ как единственную точку входа в контур.
380
+
381
+ Плагин пинует точную версию пакета (не нижний порог: «ровно эта версия», не «эта или новее») в
382
+ собственном файле совместимости. Если что-то в интеграции с плагином ведёт себя не так, как
383
+ описано в его документации, — первым делом сверьте версию:
384
+
385
+ ```bash
386
+ ktalk --version # см. «Проверка версии» в разделе «Установка»
387
+ ```
388
+
389
+ Версия не совпадает с той, что требует плагин, — обновите пакет тем же способом, что при
390
+ установке (`uv tool upgrade ktalk-cli`, см. «Установка»); не совпадает в другую сторону
391
+ (пакет новее, чем ожидает плагин) — не откатывайте его самостоятельно, сверьтесь с тем, кто
392
+ настраивал плагин.
393
+
394
+ ## Проблемы и вопросы
395
+
396
+ Нашли баг, некорректное поведение или неточность в документации — заведите issue в этом
397
+ репозитории: https://github.com/mdemyanov/ktalk-cli/issues.
398
+
389
399
  ## Лицензия
390
400
 
391
401
  MIT