qwencode-branch-stats 0.24.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 (32) hide show
  1. qwencode_branch_stats-0.24.0.0/LICENSE +21 -0
  2. qwencode_branch_stats-0.24.0.0/PKG-INFO +507 -0
  3. qwencode_branch_stats-0.24.0.0/README.md +480 -0
  4. qwencode_branch_stats-0.24.0.0/pyproject.toml +52 -0
  5. qwencode_branch_stats-0.24.0.0/setup.cfg +4 -0
  6. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/__init__.py +4 -0
  7. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/aggregation.py +265 -0
  8. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/cli.py +140 -0
  9. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/git.py +56 -0
  10. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/hooks/__init__.py +2 -0
  11. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/hooks/session_end.py +52 -0
  12. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/mappings.py +87 -0
  13. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/models.py +147 -0
  14. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/__init__.py +2 -0
  15. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/jsonl.py +37 -0
  16. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/paths.py +42 -0
  17. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/sessions.py +60 -0
  18. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/settings.py +35 -0
  19. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/subagents.py +72 -0
  20. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/tools.py +100 -0
  21. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/usage.py +71 -0
  22. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/reports/__init__.py +2 -0
  23. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/reports/json_report.py +19 -0
  24. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/reports/markdown_report.py +142 -0
  25. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/service.py +72 -0
  26. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/PKG-INFO +507 -0
  27. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/SOURCES.txt +30 -0
  28. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/dependency_links.txt +1 -0
  29. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/entry_points.txt +3 -0
  30. qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/top_level.txt +1 -0
  31. qwencode_branch_stats-0.24.0.0/tests/test_qwencode_branch_stats.py +217 -0
  32. qwencode_branch_stats-0.24.0.0/tests/test_version.py +40 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 qwencode-branch-stats contributors
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,507 @@
1
+ Metadata-Version: 2.4
2
+ Name: qwencode-branch-stats
3
+ Version: 0.24.0.0
4
+ Summary: Local Qwen Code usage metrics by Git repository and branch
5
+ Author: qwencode-branch-stats contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/helhrave/qwencode-branch-stats
8
+ Project-URL: Repository, https://github.com/helhrave/qwencode-branch-stats
9
+ Project-URL: Issues, https://github.com/helhrave/qwencode-branch-stats/issues
10
+ Keywords: qwen,qwen-code,cli,git,statistics,metrics
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Dynamic: license-file
27
+
28
+ # qwencode-branch-stats
29
+
30
+ `qwencode-branch-stats` (краткое имя команды из консоли — `qbs`) —
31
+ кроссплатформенный CLI-инструмент на Python для расчёта
32
+ стоимости и метрик использования Qwen Code в разрезе Git-ветки.
33
+
34
+ ## 1. Что делает приложение
35
+
36
+ Инструмент связывает завершённые Qwen Code sessions с текущими Git repository
37
+ и branch, читает локальную телеметрию Qwen, а затем создаёт два согласованных
38
+ отчёта:
39
+
40
+ - `report.md` — удобный отчёт для человека;
41
+ - `report.json` — те же данные в машиночитаемом виде.
42
+
43
+ В отчёте показываются:
44
+
45
+ - общая стоимость работы в ветке;
46
+ - стоимость, запросы и токены по моделям;
47
+ - стоимость по sessions, main agent и именам subagents;
48
+ - input, cached input, output и reasoning tokens;
49
+ - API duration, tool duration и subagent duration;
50
+ - вызовы обычных tools и MCP tools;
51
+ - количество и иерархия запусков subagents;
52
+ - предупреждения о неполных или повреждённых данных.
53
+
54
+ Одна ветка может включать несколько sessions, например «Исследование»,
55
+ «Реализация» и «Написание тестов». Одна session может использовать несколько
56
+ моделей.
57
+
58
+ Отчёты сохраняются в папку `.qbs/` в корне проекта и автоматически
59
+ обновляются при завершении каждой Qwen session (через `SessionEnd` hook).
60
+ Команду `qbs report` можно запускать в любой момент — она перестраивает те же
61
+ файлы заново из исходных данных.
62
+
63
+ ### Пример отчёта
64
+
65
+ Фрагмент `report.md`:
66
+
67
+ ```markdown
68
+ # feature/PROJ-1234-add-cache
69
+
70
+ Repository: my-project
71
+ Branch: feature/PROJ-1234-add-cache
72
+ Sessions: 3
73
+ Observation span: 2026-09-17T10:20:00Z — 2026-09-18T14:45:00Z
74
+
75
+ ## Cost by model
76
+
77
+ | Model | Requests | Input | Cached | Output | Reasoning | Cost |
78
+ |---|---:|---:|---:|---:|---:|---:|
79
+ | routerai/deepseek/deepseek-v4-flash | 42 | 1,200,000 | 800,000 | 15,000 | 3,000 | 7.38 |
80
+ | routerai/qwen/qwen3.8-flash | 15 | 450,000 | 300,000 | 8,000 | 1,200 | 7.61 |
81
+
82
+ Total cost: 14.99
83
+
84
+ ## Sessions
85
+
86
+ | Session | Title | Models | Requests | Input | Cached | Output | Reasoning | Cost |
87
+ |---|---|---|---:|---:|---:|---:|---:|---:|
88
+ | 18697f75… | Исследование архитектуры | deepseek-v4-flash | 17 | 410,000 | 250,000 | 6,000 | 1,200 | 3.41 |
89
+ | a1b2c3d4… | Реализация API | qwen3.8-flash | 28 | 870,000 | 590,000 | 12,000 | 2,000 | 8.17 |
90
+ | f9e8d7c6… | Написание тестов | deepseek-v4-flash, qwen3.8-flash | 12 | 370,000 | 260,000 | 5,000 | 1,000 | 3.41 |
91
+ ```
92
+
93
+ Кроме показанных таблиц, полный Markdown-отчёт содержит секции `Cost by agent`,
94
+ `Overall usage`, `Session details`, `Tools`, `MCP`, `Subagents` и
95
+ `Data quality / warnings`.
96
+
97
+ ## 2. Как начать пользоваться
98
+
99
+ ### Требования
100
+
101
+ - Python 3.10 или новее;
102
+ - Git, доступный через команду `git`;
103
+ - установленный и используемый Qwen Code;
104
+ - запуск команд внутри Git working tree.
105
+
106
+ ### Версии
107
+
108
+ Версия инструмента имеет формат
109
+ `<версия Qwen Code, на которой код проверен>.<версия приложения>` —
110
+ например, `0.24.0.0`. Версия приложения начинается с `0` на каждой версии
111
+ Qwen Code. Подробности — в разделах [Версионирование](#4-версионирование) и
112
+ [Как обновить](#5-как-обновить).
113
+
114
+ ### Установка
115
+
116
+ Из каталога с исходным кодом:
117
+
118
+ ```bash
119
+ python -m pip install .
120
+ ```
121
+
122
+ Проверка установки:
123
+
124
+ ```bash
125
+ qbs --version
126
+ ```
127
+
128
+ ### Шаг 1. Подключить SessionEnd hook
129
+
130
+ Настройте Qwen Code так, чтобы при завершении session он запускал команду:
131
+
132
+ ```bash
133
+ qbs hook session-end
134
+ ```
135
+
136
+ Hook должен получать JSON-событие Qwen через standard input. Инструмент
137
+ распознаёт идентификатор session в одном из вариантов:
138
+
139
+ ```json
140
+ {"sessionId": "18697f75-6ead-472a-b700-18afb74ab2a2"}
141
+ ```
142
+
143
+ ```json
144
+ {"session_id": "18697f75-6ead-472a-b700-18afb74ab2a2"}
145
+ ```
146
+
147
+ ```json
148
+ {"session": {"id": "18697f75-6ead-472a-b700-18afb74ab2a2"}}
149
+ ```
150
+
151
+ Точный синтаксис регистрации hook зависит от версии Qwen Code. В конфигурации
152
+ нужно указать команду выше для события `SessionEnd` и не менять рабочий каталог:
153
+ hook определяет repository и branch именно в момент завершения session.
154
+
155
+ Для ручной проверки из нужного Git-репозитория можно выполнить:
156
+
157
+ ```bash
158
+ echo '{"sessionId":"18697f75-6ead-472a-b700-18afb74ab2a2"}' \
159
+ | qbs hook session-end
160
+ ```
161
+
162
+ Также идентификатор можно передать явно:
163
+
164
+ ```bash
165
+ qbs hook session-end \
166
+ --session-id 18697f75-6ead-472a-b700-18afb74ab2a2
167
+ ```
168
+
169
+ ### Шаг 2. Работать с Qwen Code
170
+
171
+ Работайте в Git-ветке как обычно. Для удобства последующего анализа задавайте
172
+ sessions понятные custom titles средствами Qwen Code, например:
173
+
174
+ - `Исследование архитектуры`;
175
+ - `Реализация API`;
176
+ - `Написание тестов`.
177
+
178
+ Если session переименовывалась несколько раз, в отчёт попадёт последнее
179
+ сохранённое custom title. Если title не задан, значение останется пустым —
180
+ `qwencode-branch-stats` не генерирует названия самостоятельно.
181
+
182
+ ### Шаг 3. Проверить окружение
183
+
184
+ Из рабочей директории проекта:
185
+
186
+ ```bash
187
+ qbs doctor
188
+ ```
189
+
190
+ Для машиночитаемого результата:
191
+
192
+ ```bash
193
+ qbs doctor --json
194
+ ```
195
+
196
+ Команда проверяет Git-контекст, наличие каталога Qwen, `settings.json`, usage
197
+ files и число sessions, связанных с текущей веткой.
198
+
199
+ ### Шаг 4. Построить отчёт
200
+
201
+ Из нужной Git-ветки выполните:
202
+
203
+ ```bash
204
+ qbs report
205
+ ```
206
+
207
+ По умолчанию отчёты сохраняются в папку `.qbs/` в текущем каталоге.
208
+ После подключения hook из шага 1 эти файлы также автоматически
209
+ пересоздаются при каждом завершении Qwen session — отдельный запуск команды
210
+ для этого не требуется:
211
+
212
+ ```text
213
+ .qbs/
214
+ ├── report.json
215
+ └── report.md
216
+ ```
217
+
218
+ Каталог вывода можно изменить параметром `--output-dir`:
219
+
220
+ ```bash
221
+ qbs report --output-dir /path/to/reports
222
+ ```
223
+
224
+ Повторный запуск безопасен: отчёт заново строится из исходных данных Qwen.
225
+ Записи usage дедуплицируются по `usage.id`, а tool calls — по `call_id`, если
226
+ он присутствует.
227
+
228
+ ### Нестандартное расположение данных
229
+
230
+ По умолчанию Qwen-артефакты читаются из `~/.qwen`. Путь можно изменить:
231
+
232
+ ```bash
233
+ export QBS_QWEN_HOME=/path/to/qwen-data
234
+ ```
235
+
236
+ Также поддерживается переменная `QWEN_HOME`.
237
+
238
+ Расположение внутреннего хранилища связей session с Git можно изменить:
239
+
240
+ ```bash
241
+ export QBS_DATA_DIR=/path/to/qbs-data
242
+ ```
243
+
244
+ Для разового запуска доступны параметры `--qwen-home` и `--data-dir`:
245
+
246
+ ```bash
247
+ qbs report \
248
+ --qwen-home /path/to/qwen-data \
249
+ --data-dir /path/to/qbs-data
250
+ ```
251
+
252
+ В Windows используйте синтаксис переменных окружения и путей, соответствующий
253
+ PowerShell или `cmd.exe`.
254
+
255
+ ## 3. Как работает
256
+
257
+ ### Общая схема
258
+
259
+ ```text
260
+ Qwen Code session
261
+
262
+ │ SessionEnd
263
+
264
+ session ID → repository → branch
265
+
266
+ │ qbs report или SessionEnd hook
267
+
268
+ ┌─────────────────────────────────────────┐
269
+ │ token usage + chats + subagents │
270
+ │ + model pricing │
271
+ └───────────────────┬─────────────────────┘
272
+
273
+ нормализация и агрегация
274
+
275
+ ┌──────┴──────┐
276
+ ▼ ▼
277
+ report.json report.md
278
+ ```
279
+
280
+ ### 3.1. Привязка session к Git-ветке
281
+
282
+ Команда `qbs hook session-end` получает session ID и запускает:
283
+
284
+ ```bash
285
+ git rev-parse --show-toplevel
286
+ git branch --show-current
287
+ ```
288
+
289
+ Полученная связь сохраняется локально:
290
+
291
+ ```text
292
+ session ID + абсолютный путь repository + branch + captured_at
293
+ ```
294
+
295
+ Абсолютный нормализованный путь позволяет различать репозитории с одинаковыми
296
+ названиями веток. Каждая session хранится в отдельном атомарно заменяемом файле,
297
+ поэтому несколько Qwen-процессов могут завершаться параллельно.
298
+
299
+ В сами отчёты в качестве repository попадает только название папки проекта —
300
+ папки, в которой находится `.git`. Полный путь используется лишь как внутренний
301
+ идентификатор в хранилище связей и в отчёт не записывается.
302
+
303
+ После сохранения связи хук автоматически перестраивает `report.json` и
304
+ `report.md` в папку `.qbs/` этого repository, поэтому отчёты актуальны сразу
305
+ после завершения session. Если построение отчёта не удалось, сохранённый
306
+ mapping не откатывается — текст ошибки выводится в stderr хука.
307
+
308
+ ### 3.2. Поиск sessions для отчёта
309
+
310
+ При запуске `qbs report` инструмент снова определяет текущие repository
311
+ и branch, после чего выбирает только связанные с этой комбинацией завершённые
312
+ sessions.
313
+
314
+ Команда `qwen sessions list` не используется: все данные читаются напрямую из
315
+ локальных артефактов Qwen Code.
316
+
317
+ ### 3.3. Источники данных
318
+
319
+ | Метрика | Источник |
320
+ |---|---|
321
+ | Repository и branch | SessionEnd hook + Git |
322
+ | Title и время session | `~/.qwen/projects/.../chats/<session-id>.jsonl` |
323
+ | Модели, токены и API duration | `~/.qwen/usage/token-usage-YYYY-MM.jsonl` |
324
+ | Цена моделей | `~/.qwen/settings.json` → `modelPricing` |
325
+ | Main tools и MCP | transcript основной session |
326
+ | Запуски и иерархия subagents | `subagents/<session-id>/*.meta.json` |
327
+ | Tools subagents | `subagents/<session-id>/*.jsonl` |
328
+
329
+ JSONL-файлы обрабатываются построчно. Сначала выполняется фильтрация по нужным
330
+ session IDs, поэтому большие usage и transcript files не загружаются целиком в
331
+ память.
332
+
333
+ ### 3.4. Расчёт стоимости
334
+
335
+ Для каждого LLM request цена берётся из `settings.json` и рассчитывается так:
336
+
337
+ ```text
338
+ input cost = inputTokens / 1 000 000 × inputPerMillionTokens
339
+ output cost = outputTokens / 1 000 000 × outputPerMillionTokens
340
+ cost = input cost + output cost
341
+ ```
342
+
343
+ `cachedTokens` показываются отдельно, но при текущей структуре Qwen pricing не
344
+ имеют отдельного тарифа и уже входят в расчёт через `inputTokens`.
345
+
346
+ `thoughtsTokens` выводятся как reasoning tokens и не прибавляются повторно к
347
+ `outputTokens`.
348
+
349
+ Далее каждый request агрегируется по:
350
+
351
+ ```text
352
+ session + model + agent → session → repository + branch
353
+ ```
354
+
355
+ Если для хотя бы одной использованной модели нет pricing, её стоимость и
356
+ зависящие от неё общие суммы получают значение `null` в JSON и `unknown` в
357
+ Markdown. В отчёт также добавляется warning `pricing_missing` — частичная сумма
358
+ не выдаётся за полную.
359
+
360
+ ### 3.5. Tools, MCP и subagents
361
+
362
+ Tool calls группируются по имени инструмента. Для каждого имени считаются:
363
+
364
+ - общее число вызовов;
365
+ - успешные и неуспешные вызовы;
366
+ - суммарная длительность.
367
+
368
+ Имена вида:
369
+
370
+ ```text
371
+ mcp__gitlab__get_mcp_server_version
372
+ ```
373
+
374
+ нормализуются в MCP server `gitlab` и tool `get_mcp_server_version`. MCP-вызовы
375
+ одновременно входят в общее число tool calls.
376
+
377
+ Запуски subagents считаются по metadata files. Поля `parentSessionId`,
378
+ `parentAgentId` и `depth` сохраняют иерархию вложенных агентов. Расходы LLM
379
+ агрегируются по значению `source`, например `main` или `general-purpose`.
380
+
381
+ ### 3.6. Предупреждения и частичные данные
382
+
383
+ Отсутствие части данных не останавливает построение отчёта. Вместо этого в
384
+ `report.json` и `report.md` добавляются warnings, например:
385
+
386
+ - `pricing_missing`;
387
+ - `session_mapping_missing`;
388
+ - `transcript_missing`;
389
+ - `subagent_metadata_missing`;
390
+ - `malformed_jsonl`;
391
+ - `unknown_qwen_schema`.
392
+
393
+ Так можно получить доступные метрики и одновременно увидеть, какие значения
394
+ нельзя считать полными.
395
+
396
+ ### 3.7. Приватность
397
+
398
+ В отчёты попадают только необходимые metadata и числовые метрики. Инструмент не
399
+ копирует исходные Qwen events целиком и не записывает в отчёты:
400
+
401
+ - prompts и ответы assistant;
402
+ - reasoning text;
403
+ - аргументы и результаты tools;
404
+ - shell-команды и их вывод;
405
+ - MCP payloads;
406
+ - содержимое файлов;
407
+ - API keys и credentials;
408
+ - полные пути repository на диске.
409
+
410
+ Разрешены session titles, названия моделей, agents и tools, MCP server/tool,
411
+ название папки проекта и Git branch, timestamps, statuses и числовые показатели.
412
+
413
+ ## 4. Версионирование
414
+
415
+ Формат версии `qwencode-branch-stats`:
416
+ `<версия Qwen Code, на которой код проверен>.<версия приложения>`.
417
+ Например, версия `0.24.0.1` означает, что код протестирован с Qwen Code
418
+ `0.24.0` (`qwen --version`) и это второй релиз приложения на ней. Версия
419
+ приложения начинается с `0` на каждой версии Qwen Code и увеличивается на 1
420
+ при каждом следующем релизе на той же версии Qwen Code.
421
+
422
+ Совпадать должны три значения; четвёртое выводится из них:
423
+
424
+ | Место | Пример значения |
425
+ |----------------------------------------------------------|-------------------------------------|
426
+ | git tag репозитория | `0.24.0.0` |
427
+ | `version` в `[project]` внутри `pyproject.toml` | `0.24.0.0` |
428
+ | `__version__` в `src/qwencode_branch_stats/__init__.py` | `0.24.0.0` |
429
+ | вывод `qbs --version` | `qwencode-branch-stats 0.24.0.0` |
430
+
431
+ Версией Qwen Code, на которой проверен инструмент, является всё, кроме
432
+ последнего сегмента; последний сегмент — номер релиза приложения на ней.
433
+ `qbs doctor` помогает быстро проверить совместимость с окружением.
434
+
435
+ ## 5. Как обновить
436
+
437
+ ### После обновления Qwen Code
438
+
439
+ 1. Узнайте версию Qwen Code:
440
+
441
+ ```bash
442
+ qwen --version
443
+ ```
444
+
445
+ 2. Проверьте код на этой версии. Тесты:
446
+
447
+ ```bash
448
+ python -m unittest discover -s tests -v
449
+ ```
450
+
451
+ Затем прогоните одну реальную Qwen session и убедитесь, что SessionEnd
452
+ hook сохранил mapping и обновил `.qbs/report.md` и `.qbs/report.json`
453
+ с корректными метриками. Диагностика — `qbs doctor`.
454
+
455
+ 3. Если проверка прошла, поднимите версию до `<версия Qwen Code>.0` в трёх
456
+ местах (git tag, `pyproject.toml`, `__version__`) — для Qwen Code
457
+ `0.25.0` это `0.25.0.0` — и переустановите пакет:
458
+
459
+ ```bash
460
+ pip install --force-reinstall --no-deps .
461
+ qbs --version
462
+ ```
463
+
464
+ 4. Если parsers не разбирают артефакты новой версии Qwen Code (изменились
465
+ форматы usage, chats, subagents или `settings.json`), версию не
466
+ поднимайте: сначала почините разбор (`qwen/` и `aggregation.py`),
467
+ затем повторите проверку.
468
+
469
+ ### Релиз приложения на той же версии Qwen Code
470
+
471
+ Если код меняется, а версия проверенного Qwen Code та же (`X`), растёт
472
+ только версия приложения: `X.N` → `X.N+1`. Например, второй релиз на
473
+ Qwen Code `0.24.0` — это `0.24.0.1`.
474
+
475
+ ### Установка версии под конкретный Qwen Code
476
+
477
+ Релизы соответствуют git tag:
478
+
479
+ ```bash
480
+ git checkout 0.24.0.0
481
+ pip install .
482
+ ```
483
+
484
+ ## Основные команды
485
+
486
+ ```bash
487
+ # Зафиксировать Git-контекст завершённой session и обновить отчёты в .qbs/
488
+ qbs hook session-end
489
+
490
+ # Проверить окружение
491
+ qbs doctor
492
+
493
+ # Построить report.json и report.md (по умолчанию в .qbs/)
494
+ qbs report
495
+
496
+ # Показать версию
497
+ qbs --version
498
+ ```
499
+
500
+ ## Запуск тестов
501
+
502
+ Проект использует стандартный `unittest`, дополнительные test dependencies не
503
+ требуются:
504
+
505
+ ```bash
506
+ python -m unittest discover -s tests -v
507
+ ```