ktalk-cli 1.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 (109) hide show
  1. ktalk_cli-1.0.0/.gitignore +29 -0
  2. ktalk_cli-1.0.0/LICENSE +21 -0
  3. ktalk_cli-1.0.0/PKG-INFO +391 -0
  4. ktalk_cli-1.0.0/README.md +368 -0
  5. ktalk_cli-1.0.0/pyproject.toml +75 -0
  6. ktalk_cli-1.0.0/src/ktalk_cli/CLAUDE.md +30 -0
  7. ktalk_cli-1.0.0/src/ktalk_cli/__init__.py +23 -0
  8. ktalk_cli-1.0.0/src/ktalk_cli/auth.py +267 -0
  9. ktalk_cli-1.0.0/src/ktalk_cli/calendar_reader.py +149 -0
  10. ktalk_cli-1.0.0/src/ktalk_cli/cli.py +445 -0
  11. ktalk_cli-1.0.0/src/ktalk_cli/cli_contacts.py +55 -0
  12. ktalk_cli-1.0.0/src/ktalk_cli/cli_content.py +167 -0
  13. ktalk_cli-1.0.0/src/ktalk_cli/cli_meeting.py +68 -0
  14. ktalk_cli-1.0.0/src/ktalk_cli/cli_meeting_args.py +123 -0
  15. ktalk_cli-1.0.0/src/ktalk_cli/cli_meeting_confirm.py +256 -0
  16. ktalk_cli-1.0.0/src/ktalk_cli/cli_meetings_read.py +115 -0
  17. ktalk_cli-1.0.0/src/ktalk_cli/cli_sanction.py +108 -0
  18. ktalk_cli-1.0.0/src/ktalk_cli/cli_store.py +59 -0
  19. ktalk_cli-1.0.0/src/ktalk_cli/cli_sync.py +169 -0
  20. ktalk_cli-1.0.0/src/ktalk_cli/cli_token.py +88 -0
  21. ktalk_cli-1.0.0/src/ktalk_cli/client.py +348 -0
  22. ktalk_cli-1.0.0/src/ktalk_cli/config.py +152 -0
  23. ktalk_cli-1.0.0/src/ktalk_cli/confirmation.py +129 -0
  24. ktalk_cli-1.0.0/src/ktalk_cli/contacts.py +45 -0
  25. ktalk_cli-1.0.0/src/ktalk_cli/contour_diagnostics.py +107 -0
  26. ktalk_cli-1.0.0/src/ktalk_cli/download.py +109 -0
  27. ktalk_cli-1.0.0/src/ktalk_cli/endpoints.py +145 -0
  28. ktalk_cli-1.0.0/src/ktalk_cli/enrichment.py +83 -0
  29. ktalk_cli-1.0.0/src/ktalk_cli/formatters.py +589 -0
  30. ktalk_cli-1.0.0/src/ktalk_cli/host_config.py +136 -0
  31. ktalk_cli-1.0.0/src/ktalk_cli/meeting_body.py +178 -0
  32. ktalk_cli-1.0.0/src/ktalk_cli/meeting_cancel.py +33 -0
  33. ktalk_cli-1.0.0/src/ktalk_cli/meeting_scheduling.py +120 -0
  34. ktalk_cli-1.0.0/src/ktalk_cli/pagination.py +108 -0
  35. ktalk_cli-1.0.0/src/ktalk_cli/reconciliation.py +59 -0
  36. ktalk_cli-1.0.0/src/ktalk_cli/registry.py +562 -0
  37. ktalk_cli-1.0.0/src/ktalk_cli/rooms.py +62 -0
  38. ktalk_cli-1.0.0/src/ktalk_cli/store.py +88 -0
  39. ktalk_cli-1.0.0/src/ktalk_cli/store_migration.py +89 -0
  40. ktalk_cli-1.0.0/src/ktalk_cli/token_file.py +101 -0
  41. ktalk_cli-1.0.0/src/ktalk_cli/write_journal.py +94 -0
  42. ktalk_cli-1.0.0/src/ktalk_cli/write_sanction.py +187 -0
  43. ktalk_cli-1.0.0/tests/conftest.py +16 -0
  44. ktalk_cli-1.0.0/tests/fixtures/access-info-expired.json +6 -0
  45. ktalk_cli-1.0.0/tests/fixtures/access-info-full.json +7 -0
  46. ktalk_cli-1.0.0/tests/fixtures/archive-8col.md +5 -0
  47. ktalk_cli-1.0.0/tests/fixtures/archive-dup-id.md +5 -0
  48. ktalk_cli-1.0.0/tests/fixtures/archive-escaped-pipe-7col.md +5 -0
  49. ktalk_cli-1.0.0/tests/fixtures/archive-page1.json +8 -0
  50. ktalk_cli-1.0.0/tests/fixtures/archive-page2-empty.json +3 -0
  51. ktalk_cli-1.0.0/tests/fixtures/archive-pipe-in-name.md +5 -0
  52. ktalk_cli-1.0.0/tests/fixtures/calendar-item-session.json +22 -0
  53. ktalk_cli-1.0.0/tests/fixtures/chat-messages-session.json +6 -0
  54. ktalk_cli-1.0.0/tests/fixtures/conference-history-session-oversized.json +19 -0
  55. ktalk_cli-1.0.0/tests/fixtures/conference-history-session.json +17 -0
  56. ktalk_cli-1.0.0/tests/fixtures/error-body-problem-json.json +6 -0
  57. ktalk_cli-1.0.0/tests/fixtures/error-body-validation.json +6 -0
  58. ktalk_cli-1.0.0/tests/fixtures/recording-detail-session-full-participants.json +15 -0
  59. ktalk_cli-1.0.0/tests/fixtures/recording-detail-session-oversized-partial.json +16 -0
  60. ktalk_cli-1.0.0/tests/fixtures/recording-detail-with-qualities.json +10 -0
  61. ktalk_cli-1.0.0/tests/fixtures/recording-list-item-session.json +19 -0
  62. ktalk_cli-1.0.0/tests/fixtures/recordings-list-apikey-page1.json +10 -0
  63. ktalk_cli-1.0.0/tests/fixtures/recordings-list-apikey-page2.json +8 -0
  64. ktalk_cli-1.0.0/tests/fixtures/registry-archive-2026-04.md +11 -0
  65. ktalk_cli-1.0.0/tests/fixtures/registry.md +12 -0
  66. ktalk_cli-1.0.0/tests/fixtures/room-detail-session.json +20 -0
  67. ktalk_cli-1.0.0/tests/test_adr022_ktalk_cli_rename.py +166 -0
  68. ktalk_cli-1.0.0/tests/test_archive.py +35 -0
  69. ktalk_cli-1.0.0/tests/test_auth_modes.py +243 -0
  70. ktalk_cli-1.0.0/tests/test_calendar.py +385 -0
  71. ktalk_cli-1.0.0/tests/test_chat.py +88 -0
  72. ktalk_cli-1.0.0/tests/test_cli.py +307 -0
  73. ktalk_cli-1.0.0/tests/test_cli_config_show.py +111 -0
  74. ktalk_cli-1.0.0/tests/test_cli_content.py +267 -0
  75. ktalk_cli-1.0.0/tests/test_cli_export_store_isolation.py +59 -0
  76. ktalk_cli-1.0.0/tests/test_cli_host_config_wiring.py +189 -0
  77. ktalk_cli-1.0.0/tests/test_cli_meeting.py +494 -0
  78. ktalk_cli-1.0.0/tests/test_cli_meeting_sanctioned.py +272 -0
  79. ktalk_cli-1.0.0/tests/test_cli_meetings_surface.py +388 -0
  80. ktalk_cli-1.0.0/tests/test_cli_migrate_to_central_store.py +111 -0
  81. ktalk_cli-1.0.0/tests/test_client.py +180 -0
  82. ktalk_cli-1.0.0/tests/test_concurrency.py +162 -0
  83. ktalk_cli-1.0.0/tests/test_config.py +137 -0
  84. ktalk_cli-1.0.0/tests/test_confirmation.py +141 -0
  85. ktalk_cli-1.0.0/tests/test_contour_diagnostics.py +304 -0
  86. ktalk_cli-1.0.0/tests/test_diagnostics.py +224 -0
  87. ktalk_cli-1.0.0/tests/test_download.py +163 -0
  88. ktalk_cli-1.0.0/tests/test_enrichment.py +172 -0
  89. ktalk_cli-1.0.0/tests/test_formatters.py +652 -0
  90. ktalk_cli-1.0.0/tests/test_fr19_auth_status.py +110 -0
  91. ktalk_cli-1.0.0/tests/test_fr21_no_vault_layout.py +76 -0
  92. ktalk_cli-1.0.0/tests/test_fr39_calendar_inclusive_end.py +266 -0
  93. ktalk_cli-1.0.0/tests/test_fr40_timezone_format.py +319 -0
  94. ktalk_cli-1.0.0/tests/test_host_config.py +249 -0
  95. ktalk_cli-1.0.0/tests/test_meeting_body.py +352 -0
  96. ktalk_cli-1.0.0/tests/test_meeting_cancel.py +417 -0
  97. ktalk_cli-1.0.0/tests/test_meeting_scheduling.py +397 -0
  98. ktalk_cli-1.0.0/tests/test_migration.py +173 -0
  99. ktalk_cli-1.0.0/tests/test_pagination.py +360 -0
  100. ktalk_cli-1.0.0/tests/test_reconciliation.py +213 -0
  101. ktalk_cli-1.0.0/tests/test_registry.py +284 -0
  102. ktalk_cli-1.0.0/tests/test_rooms.py +194 -0
  103. ktalk_cli-1.0.0/tests/test_search_contacts.py +310 -0
  104. ktalk_cli-1.0.0/tests/test_secret_masking.py +323 -0
  105. ktalk_cli-1.0.0/tests/test_store.py +293 -0
  106. ktalk_cli-1.0.0/tests/test_store_migration.py +239 -0
  107. ktalk_cli-1.0.0/tests/test_token_file.py +287 -0
  108. ktalk_cli-1.0.0/tests/test_write_journal.py +144 -0
  109. ktalk_cli-1.0.0/tests/test_write_sanction.py +236 -0
@@ -0,0 +1,29 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .env
10
+ .venv/
11
+ venv/
12
+ .pytest_cache/
13
+ .ruff_cache/
14
+ .mypy_cache/
15
+ .claude/settings.local.json
16
+ .worktrees/
17
+
18
+ # Снимки DevTools: содержат живые токены, куки и перс. данные (NFR-5/SEC-001)
19
+ docs/*-recording.json
20
+ docs/calendar
21
+ docs/*.har
22
+
23
+ # Beads / Dolt files (added by bd init)
24
+ .dolt/
25
+ *.db
26
+ .beads-credential-key
27
+ .beads/proxieddb/
28
+ *.gate.lock*
29
+ packaging/*/dist/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Maksim Demyanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,391 @@
1
+ Metadata-Version: 2.5
2
+ Name: ktalk-cli
3
+ Version: 1.0.0
4
+ Summary: CLI for accessing Kontur Talk (KTalk) recordings, transcripts and summaries
5
+ Project-URL: Homepage, https://github.com/mdemyanov/ktalk-cli
6
+ Project-URL: Repository, https://github.com/mdemyanov/ktalk-cli
7
+ Project-URL: Issues, https://github.com/mdemyanov/ktalk-cli/issues
8
+ Author-email: Maksim Demyanov <mdemyanov@users.noreply.github.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,kontur,ktalk,recordings,transcripts
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Communications :: Conferencing
19
+ Requires-Python: >=3.12
20
+ Requires-Dist: httpx>=0.28.0
21
+ Requires-Dist: pydantic-settings>=2.0.0
22
+ Description-Content-Type: text/markdown
23
+
24
+ # ktalk-cli
25
+
26
+ [![PyPI](https://img.shields.io/pypi/v/ktalk-cli)](https://pypi.org/project/ktalk-cli/)
27
+ [![Python](https://img.shields.io/pypi/pyversions/ktalk-cli)](https://pypi.org/project/ktalk-cli/)
28
+
29
+ CLI `ktalk` для доступа к записям [Контур.Толк](https://ktalk.ru) (KTalk) — чтение
30
+ записей, транскриптов и саммари, работа с расписанием, операционный реестр
31
+ обработки записей на SQLite.
32
+
33
+ > Раньше пакет назывался `ktalk-mcp` и, помимо CLI, поднимал MCP-сервер для
34
+ > Claude Code (инструменты вида `ktalk_list_recordings`). Этот слой снят
35
+ > целиком — MCP в пакете больше нет, единственная точка входа — команда
36
+ > `ktalk`. Нужна интеграция с Claude Code — отдельный плагин `ktalk` вызывает
37
+ > эту же CLI напрямую, без MCP-сервера.
38
+
39
+ Умеет:
40
+ - Список записей конференций и детали одной записи.
41
+ - Транскрипты (речь по спикерам с таймкодами, с чанкингом для длинных).
42
+ - Саммари и протоколы встреч.
43
+ - Полный состав участников записи (обходит лимит в 6 из списковых ответов).
44
+ - Скачивание видеофайла записи.
45
+ - Архив встреч и историю чата (только с персональным API-ключом).
46
+ - Конфигурацию комнаты и календарь запланированных встреч (только с session token).
47
+ - Предпросмотр и создание новой встречи — создание требует интерактивного
48
+ терминала и явного подтверждения, см. «Планирование встречи» ниже.
49
+ - Диагностику авторизации — какой ключ/токен активен и почему запрос не проходит.
50
+ - Операционный реестр обработки записей на SQLite — синхронизация, статусы,
51
+ markdown-зеркало для git, см. «Реестр записей» ниже.
52
+
53
+ ## Установка
54
+
55
+ Требуется Python 3.12+ и [uv](https://docs.astral.sh/uv/).
56
+
57
+ ```bash
58
+ uv tool install ktalk-cli
59
+ ```
60
+
61
+ Или через pip:
62
+
63
+ ```bash
64
+ pip install ktalk-cli
65
+ ```
66
+
67
+ **Если на машине уже стоит старый `ktalk-mcp`** (он тоже владел командой
68
+ `ktalk`), `uv tool install ktalk-cli` откажет: `uv` не отдаёт занятое имя
69
+ команды второму пакету молча. Сначала освободите имя:
70
+
71
+ ```bash
72
+ uv tool uninstall ktalk-mcp
73
+ uv tool install ktalk-cli
74
+ ```
75
+
76
+ ## Авторизация
77
+
78
+ CLI поддерживает два способа авторизации: session token (кука браузера) и
79
+ персональный API-ключ. Способы исключают друг друга: если задать обе переменные,
80
+ побеждает `KTALK_PERSONAL_API_KEY` — `KTALK_SESSION_TOKEN` в этом случае вообще не
81
+ читается. Не задать ни один — команда завершится понятной ошибкой.
82
+
83
+ Персональный API-ключ не привязан к браузерной сессии и не протухает без предупреждения,
84
+ в отличие от session token. Берите его, если нужна стабильная работа без ручного
85
+ обновления, а не только разовый запрос.
86
+
87
+ ### Session token
88
+
89
+ Session token — токен вашей браузерной сессии Толка. Быстрый способ начать, но
90
+ токен живёт недолго и протухает без предупреждения — при регулярном
91
+ использовании удобнее персональный API-ключ (ниже).
92
+
93
+ **Два шага.** На вкладке, где вы залогинены в `https://your-domain.ktalk.ru`, откройте
94
+ DevTools (`F12`, или `Cmd+Option+I` на Mac) → **Console** и выполните:
95
+
96
+ ```js
97
+ copy(JSON.parse(localStorage.session).data.token)
98
+ ```
99
+
100
+ Токен — в буфере обмена. Положите его в файл одной командой:
101
+
102
+ ```bash
103
+ pbpaste | ktalk token set - # macOS
104
+ xclip -o | ktalk token set - # Linux (X11)
105
+ ```
106
+
107
+ Команда сама создаёт `~/.config/ktalk-mcp/token` с правами `0600` (каталог — `0700`),
108
+ отвергает значение, не похожее на токен, и никогда не печатает его в вывод. Проверка:
109
+
110
+ ```bash
111
+ ktalk token status # есть ли файл, права, маска значения
112
+ ktalk auth-status # жива ли авторизация — реальный запрос, не имитация
113
+ ```
114
+
115
+ Путь переопределяется переменной `KTALK_TOKEN_FILE`; каталог уважает `XDG_CONFIG_HOME`.
116
+
117
+ **Порядок источников** — первый непустой выигрывает:
118
+
119
+ | # | Источник | Комментарий |
120
+ |---|---|---|
121
+ | 1 | `KTALK_PERSONAL_API_KEY` | режим персонального ключа, сессия дальше не читается |
122
+ | 2 | `KTALK_SESSION_TOKEN` (окружение или `.env` в рабочей директории) | заданное явно сильнее лежащего на диске |
123
+ | 3 | `~/.config/ktalk-mcp/token` | дефолтный путь для повседневной работы |
124
+
125
+ > Путь `~/.config/ktalk-mcp/token` не переименован вместе с пакетом и остаётся
126
+ > таким намеренно: он выбран независимо от имени дистрибутива (каталог
127
+ > `ktalk/` уже занят другим — санкцией на запись, у неё свой жизненный цикл),
128
+ > а смена пути молча лишила бы уже настроенные машины третьего источника
129
+ > авторизации.
130
+
131
+ Токен из файла обслуживает и чтение, и запись: создание и отмена встречи шлют то же
132
+ значение другим транспортом (заголовок `Authorization: Session`, а не query-параметр) —
133
+ источник значения транспорт не меняет. Санкция на запись при этом остаётся обязательной,
134
+ она к токену отношения не имеет.
135
+
136
+ Файл с правами шире `0600` читается так, будто его нет (`ktalk token status` покажет
137
+ `usable: False`) — секрет не должен молча читаться с диска, доступного другим
138
+ пользователям машины.
139
+
140
+ > **Важно:** session token имеет ограниченный срок жизни. Если команда возвращает
141
+ > ошибку авторизации, повторите те же два шага — `ktalk token set -` перезаписывает
142
+ > файл, права переставлять не нужно.
143
+
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
+ ### Переменные окружения
180
+
181
+ ```bash
182
+ export KTALK_PERSONAL_API_KEY="ваш_персональный_api_ключ"
183
+ # или
184
+ export KTALK_SESSION_TOKEN="ваш_session_token"
185
+ export KTALK_BASE_URL="https://your-domain.ktalk.ru"
186
+ ```
187
+
188
+ Для session-режима переменная не обязательна: без неё читается файл
189
+ `~/.config/ktalk-mcp/token` (см. «Session token»).
190
+
191
+ Также поддерживается файл `.env` в рабочей директории:
192
+
193
+ ```env
194
+ KTALK_PERSONAL_API_KEY=ваш_персональный_api_ключ
195
+ KTALK_BASE_URL=https://your-domain.ktalk.ru
196
+ ```
197
+
198
+ ## Диагностика авторизации
199
+
200
+ Проверьте авторизацию без запроса записей:
201
+
202
+ ```bash
203
+ ktalk auth-status
204
+ ```
205
+
206
+ Диагностика различает два случая, которые снаружи выглядят одинаково — просто ошибка, —
207
+ но чинятся по-разному:
208
+
209
+ - **401** — ключ или токен невалиден либо истёк. Перевыпустите его.
210
+ - **403** — ключ рабочий, но конкретному запросу не хватает прав (scope). Отредактируйте
211
+ права ключа в админке Толка (см. таблицу в разделе «Персональный API-ключ» выше) —
212
+ перевыпускать ключ не нужно.
213
+
214
+ У session token понятия scope нет — диагностика в этом режиме пробным запросом списка
215
+ записей сообщает только «токен работает / не работает», без прав и срока действия.
216
+
217
+ Режим ключа не проверен полностью на боевом окружении — команда описывает задуманное
218
+ поведение, а не гарантию для любого ключа.
219
+
220
+ ## Команды чтения записей и справочников
221
+
222
+ Все команды поддерживают `--json` (валидный JSON в stdout; ошибки — в stderr с
223
+ ненулевым кодом возврата).
224
+
225
+ | Команда | Назначение |
226
+ |---|---|
227
+ | `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
+ | `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 токенов). |
230
+ | `ktalk get-summary <recording_key>` | Полное саммари (краткое резюме + протокол). |
231
+ | `ktalk get-summary-type <recording_key> --type shortSummary\|protocol` | Саммари одного типа. |
232
+ | `ktalk get-participants <recording_key>` | Полный состав участников, включая анонимных — обходит лимит в 6, который отдают `get-recording`/`list-recordings`. |
233
+ | `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. Сервер лимитирует один запрос семью днями и сотней встреч на сегмент — команда сама режет произвольное окно на сегменты; при упоре в потолок ответ предупреждает о возможно неполной выдаче. |
238
+
239
+ ## Планирование встречи
240
+
241
+ Создание встречи — единственная операция пакета, которая что-то меняет вне вашего
242
+ компьютера: она рассылает приглашения реальным людям. Удаление созданного события
243
+ эти письма не отзывает. Из-за этого создание устроено умышленно неудобно:
244
+
245
+ - Создание — команда `ktalk create-meeting-confirm`. Она работает только в
246
+ интерактивном терминале (проверяет, что и ввод, и вывод — реальный TTY) и
247
+ перед отправкой печатает предпросмотр и требует набрать слово `да`.
248
+ - Предпросмотр без создания — `ktalk create-meeting-preview`, не делает ни
249
+ одного сетевого запроса.
250
+ - Обе команды работают только в режиме session token — в режиме персонального
251
+ ключа создание встречи не подтверждено ни разу и потому отключено.
252
+
253
+ **Ни одно поле не имеет значения по умолчанию** (кроме описания встречи — пустая
254
+ строка, если не задано). Тема, начало, конец, часовой пояс, комната, участники,
255
+ анонимный доступ, PIN — каждое нужно передать явно; иначе команда откажет и назовёт,
256
+ какого поля не хватает. Так сделано намеренно: молчаливый часовой пояс сдвинет
257
+ встречу в календаре участников на другое время, а молчаливая автозапись незаметно
258
+ для организатора изменит, записывается ли встреча.
259
+
260
+ Из этого вытекают практические следствия:
261
+
262
+ - Часовой пояс принимает только форму `GMT±N` (пример `GMT+3`) — IANA-имена вида
263
+ `Europe/Moscow`, смещения ISO и аббревиатуры сервер не распознаёт.
264
+ - `--enable-auto-recording` и `--allow-anonymous` принимают только явные `true`
265
+ или `false` — «флаг просто не указан» не считается ответом.
266
+ - «Встреча без обязательных участников» — это отдельный флаг
267
+ `--no-required-attendees`, а не просто отсутствие `--required-attendee-key`.
268
+ Значение `--required-attendee-key` — числовой id участника, не логин.
269
+ - «Без PIN» — отдельный флаг `--no-pin-code`, а не пустая строка в `--pin-code`.
270
+ - `--anonymous-access-expiration` обязателен, только если `--allow-anonymous true`.
271
+
272
+ Повторяющиеся встречи в этой версии не поддерживаются — можно создать только
273
+ разовое событие.
274
+
275
+ При сетевом сбое во время создания команда не повторяет запрос сама: если сеть
276
+ оборвалась, неизвестно, ушло приглашение или нет, и автоматический повтор рискует
277
+ создать дубль. Решение о повторной попытке — за вами; перед ней стоит проверить
278
+ `ktalk list-calendar`, не появилась ли встреча уже.
279
+
280
+ Создание встречи ещё ни разу не выполнялось на боевом окружении — команда
281
+ реализует задуманное поведение, но не проверена живым вызовом.
282
+
283
+ ```bash
284
+ # Предпросмотр — без сети, без побочных эффектов
285
+ ktalk create-meeting-preview \
286
+ --subject "Синк по проекту" \
287
+ --start 2026-08-20T10:00:00 --end 2026-08-20T10:30:00 --timezone GMT+3 \
288
+ --room-name "Переговорная 1" \
289
+ --no-required-attendees \
290
+ --enable-auto-recording false --allow-anonymous false \
291
+ --no-pin-code
292
+
293
+ # Создание — только в интерактивном терминале, требует ввода "да"
294
+ ktalk create-meeting-confirm \
295
+ --subject "Синк по проекту" \
296
+ --start 2026-08-20T10:00:00 --end 2026-08-20T10:30:00 --timezone GMT+3 \
297
+ --room-name "Переговорная 1" \
298
+ --required-attendee-key 123 --required-attendee-key 456 \
299
+ --enable-auto-recording false --allow-anonymous false \
300
+ --no-pin-code
301
+ ```
302
+
303
+ ## API
304
+
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
+ Транскрипт и саммари используют один и тот же путь в обоих режимах:
314
+
315
+ | Эндпоинт | Описание |
316
+ |----------|----------|
317
+ | `GET /api/recordings/{id}/transcript` | Транскрипт |
318
+ | `GET /api/recordings/v2/{id}/summary` | Полное саммари (v2) |
319
+ | `GET /api/recordings/{id}/summary/{type}` | Саммари по типу |
320
+
321
+ Список записей и детали записи используют разные пути в session- и api-key-режимах.
322
+ Архив встреч, чат, полный состав участников, скачивание файла и диагностика ключа
323
+ доступны только в режиме персонального ключа (нужные права — в таблице раздела
324
+ «Персональный API-ключ» выше).
325
+
326
+ Комната, календарь и создание встречи работают только в режиме session token — в
327
+ режиме персонального ключа эти операции отказывают осознанно, а не по случайному
328
+ пробелу: путь на api-key либо не подтверждён вовсе, либо ведёт себя необъяснимо
329
+ непоследовательно при проверке.
330
+
331
+ > OpenAPI спецификация `talk.public.api-api-2.json` включена как справочник, но содержит расхождения с реальным API (пути, формат авторизации, структура ответов).
332
+
333
+ ## Реестр записей (`ktalk`)
334
+
335
+ Та же команда `ktalk` ведёт операционный реестр обработки записей на SQLite.
336
+ Вся детерминированная механика (синхронизация списка записей, дедуп,
337
+ экспирация, смена статусов, рендер дашборда и markdown-зеркала, разовая
338
+ миграция) живёт в коде, а не в рассуждениях модели.
339
+
340
+ **SQLite — операционный source of truth.** Markdown-файл `registry.md` —
341
+ генерируемое read-only зеркало для git (`ktalk export`), руками не редактируется.
342
+
343
+ Путь к базе: флаг `--db PATH` > переменная `KTALK_REGISTRY_DB` > дефолт
344
+ `95_TRANSCRIPTS/.registry.db` (относительно текущего каталога). Бинарную БД
345
+ нужно добавить в `.gitignore` (`.registry.db`, `.registry.db-wal`, `.registry.db-shm`).
346
+
347
+ `ktalk auth-status`, `ktalk create-meeting-preview` и `ktalk create-meeting-confirm`
348
+ реестр не открывают вовсе — им он не нужен. В частности, `auth-status` работает
349
+ даже если файла базы данных нет или он недоступен. Планирование встречи —
350
+ отдельный раздел «Планирование встречи» выше.
351
+
352
+ | Команда | Назначение |
353
+ |---|---|
354
+ | `ktalk sync [--days 7] [--json] [--dry-run]` | Загрузить записи из KTalk, upsert новых (`new`), экспирировать `new` старше N дней → `skipped`, показать дашборд. Идемпотентно. `--dry-run` — сверить id с реестром без записи, ничего не пишет (обязателен перед первым `sync` в режиме персонального ключа — см. «Персональный API-ключ»). |
355
+ | `ktalk token set <значение\|->` | Записать session-токен в `~/.config/ktalk-mcp/token` (`0600`). `-` — прочитать из stdin: `pbpaste \| ktalk token set -`. Значение не печатается. |
356
+ | `ktalk token status [--json]` | Есть ли файл токена, его права и маска значения. |
357
+ | `ktalk auth-status [--json]` | Диагностика активной авторизации — жив ли ключ/токен, какие права у ключа. См. «Диагностика авторизации». |
358
+ | `ktalk dashboard [--json]` | Дашборд: новые записи, статистика по статусам. |
359
+ | `ktalk list [--status S] [--json]` | Список записей с фильтром по статусу. |
360
+ | `ktalk show <id> [--json]` | Детали записи: участники, статус, пути, длительность. |
361
+ | `ktalk mark-processing <id>` | Перевести в `processing`. |
362
+ | `ktalk mark-done <id> --transcript P --protocol P [--type T]` | Завершить, проставить пути и `processed_at`. |
363
+ | `ktalk mark-partial <id> [--transcript P] [--protocol P]` | Частичная обработка. |
364
+ | `ktalk mark-skipped <id>` | Пропустить вручную. |
365
+ | `ktalk set-vault-id <id> <ktalk_id> <vault_id>` | Привязать профиль к участнику. |
366
+ | `ktalk export [--out PATH] [--full]` | Сгенерировать markdown-зеркало. |
367
+ | `ktalk migrate <vault> [--dry-run] [--json]` | Разовый импорт из markdown-реестров. |
368
+
369
+ Несколько фоновых агентов могут безопасно писать параллельно (WAL + `busy_timeout`
370
+ + транзакция на операцию).
371
+
372
+ ## Разработка
373
+
374
+ ```bash
375
+ git clone https://github.com/mdemyanov/ktalk-cli.git
376
+ cd ktalk-cli
377
+ uv sync
378
+
379
+ # Запуск тестов
380
+ uv run pytest -v
381
+
382
+ # Линтинг
383
+ uv run ruff check .
384
+
385
+ # Локальный запуск CLI (session token или KTALK_PERSONAL_API_KEY — см. «Авторизация»)
386
+ KTALK_SESSION_TOKEN=... KTALK_BASE_URL=... uv run ktalk auth-status
387
+ ```
388
+
389
+ ## Лицензия
390
+
391
+ MIT