elemctl 0.32.2__tar.gz → 0.32.3__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 (67) hide show
  1. {elemctl-0.32.2 → elemctl-0.32.3}/PKG-INFO +4 -4
  2. {elemctl-0.32.2 → elemctl-0.32.3}/README.md +2 -2
  3. {elemctl-0.32.2 → elemctl-0.32.3}/docs/SPEC.md +1 -1
  4. {elemctl-0.32.2 → elemctl-0.32.3}/docs/SPEC.ru.md +1 -1
  5. {elemctl-0.32.2 → elemctl-0.32.3}/docs/changelog.md +8 -0
  6. {elemctl-0.32.2 → elemctl-0.32.3}/docs/changelog.ru.md +8 -0
  7. {elemctl-0.32.2 → elemctl-0.32.3}/docs/index.md +2 -2
  8. {elemctl-0.32.2 → elemctl-0.32.3}/docs/index.ru.md +3 -2
  9. {elemctl-0.32.2 → elemctl-0.32.3}/docs/mcp.ru.md +1 -1
  10. {elemctl-0.32.2 → elemctl-0.32.3}/pyproject.toml +1 -1
  11. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/__init__.py +1 -1
  12. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/build.py +1 -1
  13. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/cli.py +3 -3
  14. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/mcp_server.py +1 -1
  15. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl.egg-info/PKG-INFO +4 -4
  16. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_docs_coverage.py +36 -0
  17. {elemctl-0.32.2 → elemctl-0.32.3}/.env.example +0 -0
  18. {elemctl-0.32.2 → elemctl-0.32.3}/LICENSE +0 -0
  19. {elemctl-0.32.2 → elemctl-0.32.3}/MANIFEST.in +0 -0
  20. {elemctl-0.32.2 → elemctl-0.32.3}/NOTICE +0 -0
  21. {elemctl-0.32.2 → elemctl-0.32.3}/ORIGIN.md +0 -0
  22. {elemctl-0.32.2 → elemctl-0.32.3}/docs/cli.md +0 -0
  23. {elemctl-0.32.2 → elemctl-0.32.3}/docs/cli.ru.md +0 -0
  24. {elemctl-0.32.2 → elemctl-0.32.3}/docs/config.md +0 -0
  25. {elemctl-0.32.2 → elemctl-0.32.3}/docs/config.ru.md +0 -0
  26. {elemctl-0.32.2 → elemctl-0.32.3}/docs/library.md +0 -0
  27. {elemctl-0.32.2 → elemctl-0.32.3}/docs/library.ru.md +0 -0
  28. {elemctl-0.32.2 → elemctl-0.32.3}/docs/mcp.md +0 -0
  29. {elemctl-0.32.2 → elemctl-0.32.3}/docs/platform.md +0 -0
  30. {elemctl-0.32.2 → elemctl-0.32.3}/docs/platform.ru.md +0 -0
  31. {elemctl-0.32.2 → elemctl-0.32.3}/setup.cfg +0 -0
  32. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/__main__.py +0 -0
  33. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/auth.py +0 -0
  34. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/client.py +0 -0
  35. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/config.py +0 -0
  36. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/deploy.py +0 -0
  37. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/errors.py +0 -0
  38. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/i18n.py +0 -0
  39. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/plugins.py +0 -0
  40. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/probe.py +0 -0
  41. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/schema.py +0 -0
  42. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/selfupdate.py +0 -0
  43. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/transport.py +0 -0
  44. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl/versions.py +0 -0
  45. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl.egg-info/SOURCES.txt +0 -0
  46. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl.egg-info/dependency_links.txt +0 -0
  47. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl.egg-info/entry_points.txt +0 -0
  48. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl.egg-info/requires.txt +0 -0
  49. {elemctl-0.32.2 → elemctl-0.32.3}/src/elemctl.egg-info/top_level.txt +0 -0
  50. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_build.py +0 -0
  51. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_cli.py +0 -0
  52. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_cli_docs.py +0 -0
  53. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_client.py +0 -0
  54. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_config.py +0 -0
  55. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_deploy.py +0 -0
  56. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_extract_adapter.py +0 -0
  57. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_i18n.py +0 -0
  58. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_mcp.py +0 -0
  59. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_plugins.py +0 -0
  60. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_probe.py +0 -0
  61. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_release_notes.py +0 -0
  62. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_schema.py +0 -0
  63. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_selfupdate.py +0 -0
  64. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_transport.py +0 -0
  65. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_user_lists.py +0 -0
  66. {elemctl-0.32.2 → elemctl-0.32.3}/tests/test_versions.py +0 -0
  67. {elemctl-0.32.2 → elemctl-0.32.3}/tools/extract_adapter.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elemctl
3
- Version: 0.32.2
4
- Summary: CLI, MCP server and library for the Console API v2 of the 1C:Enterprise.Element platform (1cmycloud)
3
+ Version: 0.32.3
4
+ Summary: CLI, MCP server and library for the Console API v2 of the 1C:Enterprise.Element platform (1cmycloud): applications, builds from source, one-command deploy with verification, a compile probe
5
5
  Author: KeyFire
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/keyfire/elemctl
@@ -38,9 +38,9 @@ Dynamic: license-file
38
38
 
39
39
  A command-line tool, MCP server and Python library for managing applications on the **1C:Enterprise.Element** cloud platform (1cmycloud.com) through Console API v2.
40
40
 
41
- elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
41
+ elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), check compilation with a probe that never touches the working application, and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
42
42
 
43
- *elemctl is a CLI tool, MCP server and Python library for the 1C:Enterprise.Element (1cmycloud) Console API: manage applications, upload builds and deploy with honest apply verification. The CLI output is plain JSON.*
43
+ *elemctl is a CLI tool, MCP server and Python library for the 1C:Enterprise.Element (1cmycloud) Console API: manage applications, upload builds, deploy with honest apply verification and check compilation with a probe. The CLI output is plain JSON.*
44
44
 
45
45
  Development notes and updates (in Russian): the [1C × AI: engineering workshop](https://t.me/ceh_1c_ai) Telegram channel.
46
46
 
@@ -6,9 +6,9 @@
6
6
 
7
7
  A command-line tool, MCP server and Python library for managing applications on the **1C:Enterprise.Element** cloud platform (1cmycloud.com) through Console API v2.
8
8
 
9
- elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
9
+ elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), check compilation with a probe that never touches the working application, and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
10
10
 
11
- *elemctl is a CLI tool, MCP server and Python library for the 1C:Enterprise.Element (1cmycloud) Console API: manage applications, upload builds and deploy with honest apply verification. The CLI output is plain JSON.*
11
+ *elemctl is a CLI tool, MCP server and Python library for the 1C:Enterprise.Element (1cmycloud) Console API: manage applications, upload builds, deploy with honest apply verification and check compilation with a probe. The CLI output is plain JSON.*
12
12
 
13
13
  Development notes and updates (in Russian): the [1C × AI: engineering workshop](https://t.me/ceh_1c_ai) Telegram channel.
14
14
 
@@ -12,7 +12,7 @@ The `elemctl` Python package consists of three layers on top of a shared core:
12
12
  2. **CLI** – the `elemctl` console command (entry point `elemctl` in `[project.scripts]`).
13
13
  3. **MCP server** – the same operations exposed as tools for AI agents; stdio transport; the `mcp>=1.2,<3` dependency is included as the optional extra `elemctl[mcp]` (uses the ergonomic server class of the `mcp` package: `FastMCP` in mcp 1.x, `MCPServer` in mcp 2.x).
14
14
 
15
- Package requirements: name `elemctl`, version 0.1.0, Python >= 3.10, MIT license, author KeyFire, `src/elemctl/` layout, `dev` extra with pytest. The LICENSE, README.md, .env.example, and .gitignore files are provided by the customer and are not modified.
15
+ Package requirements: name `elemctl`, version 0.1.0, Python >= 3.10, MIT license, author KeyFire, `src/elemctl/` layout, `dev` extra with pytest. The LICENSE, README.md, .env.example, and .gitignore files are given and are not modified.
16
16
 
17
17
  ## 2. Connection configuration
18
18
 
@@ -22,7 +22,7 @@ Python-пакет `elemctl` из трёх слоёв поверх общего
22
22
 
23
23
  Требования пакета: имя `elemctl`, версия 0.1.0, Python >= 3.10, лицензия MIT,
24
24
  автор KeyFire, layout `src/elemctl/`, extra `dev` с pytest. Файлы LICENSE,
25
- README.md, .env.example и .gitignore предоставлены заказчиком и не меняются.
25
+ README.md, .env.example и .gitignore заданы и не меняются.
26
26
 
27
27
  ## 2. Конфигурация подключения
28
28
 
@@ -13,6 +13,14 @@ day are named in the heading. The format follows
13
13
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
14
14
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
15
15
 
16
+ ## 2026-08-30 – 0.32.3
17
+
18
+ ### Changed
19
+
20
+ - **The package description names the probe.** The PyPI summary and the site descriptions
21
+ listed applications, builds and deploys and said nothing about the compilation check the
22
+ server runs without risking the working application – a reason of its own to pick elemctl.
23
+
16
24
  ## 2026-08-27 – 0.32.2
17
25
 
18
26
  ### Added
@@ -13,6 +13,14 @@ sidebar:
13
13
  [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/), проект следует
14
14
  [семантическому версионированию](https://semver.org/lang/ru/).
15
15
 
16
+ ## 30.08.2026 – 0.32.3
17
+
18
+ ### Изменено
19
+
20
+ - **Описание пакета называет пробник.** Сводка на карточке PyPI и описания сайта
21
+ перечисляли приложения, сборки и деплой, но молчали про проверку компиляции на сервере
22
+ без риска для рабочего приложения – а это отдельная причина ставить elemctl.
23
+
16
24
  ## 27.08.2026 – 0.32.2
17
25
 
18
26
  ### Добавлено
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Elemctl"
3
- description: "A CLI, MCP server and library for the 1C:Element Console API: applications, builds from source and one-command deploys with an honest check that the change actually landed."
3
+ description: "A CLI, MCP server and library for the 1C:Element Console API: applications, builds from source, one-command deploys with an honest check that the change actually landed, and a probe that compiles sources on the server without touching the working application."
4
4
  sidebar:
5
5
  label: Home
6
6
  order: 1
@@ -8,7 +8,7 @@ sidebar:
8
8
 
9
9
  A command-line tool, MCP server and Python library for managing applications on the **1C:Enterprise.Element** cloud platform (1cmycloud.com) through Console API v2.
10
10
 
11
- elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
11
+ elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), check compilation with a probe that never touches the working application, and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
12
12
 
13
13
  Development notes and updates (in Russian): the [1C × AI: engineering workshop](https://t.me/ceh_1c_ai) Telegram channel.
14
14
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Elemctl"
3
- description: "CLI, MCP-сервер и библиотека для Console API 1С:Элемента: приложения, сборки из исходников и деплой одной командой с честной проверкой, что изменение применилось."
3
+ description: "CLI, MCP-сервер и библиотека для Console API 1С:Элемента: приложения, сборки из исходников, деплой одной командой с честной проверкой, что изменение применилось, и пробник, который компилирует исходники на сервере, не трогая рабочее приложение."
4
4
  sidebar:
5
5
  label: Главная
6
6
  order: 1
@@ -14,6 +14,7 @@ elemctl закрывает жизненный цикл приложения на
14
14
  создать приложение, собрать архив сборки `.xasm`/`.xlib` из исходников
15
15
  проекта, загрузить сборку, применить её к приложению и убедиться, что
16
16
  применение действительно произошло (платформа умеет молча откатывать),
17
+ проверить компиляцию пробником, который не трогает рабочее приложение,
17
18
  управлять ветками среды разработки, дампами и версией технологии. Один и
18
19
  тот же движок доступен тремя способами: команда `elemctl` для терминала и
19
20
  CI, MCP-сервер для AI-агентов (Claude Code и другие MCP-клиенты) и
@@ -162,7 +163,7 @@ elemctl branches merge <branch-id>
162
163
  `deploy` и `verify` - ходить за причиной в журнал сервера не нужно.
163
164
  - Скомпилировать исходники, ничего не создавая на платформе, нельзя: компиляция
164
165
  серверная и происходит на применении сборки. Ровно для этого есть `probe` – он
165
- принимает удар на одноразовое приложение вместо рабочего. Прогон стоит
166
+ подставляет под удар одноразовое приложение вместо рабочего. Прогон стоит
166
167
  столько же, сколько создание приложения (минуты), поэтому его место перед
167
168
  деплоем или в CI, а не в цикле "на каждое нажатие".
168
169
  - Проект платформы опознаётся парой `Vendor` + `Name` манифеста, а не `Ид` из
@@ -49,7 +49,7 @@ claude mcp add elemctl -- elemctl mcp
49
49
 
50
50
  Рядом с ними встают инструменты, которые приносят плагины (см. ниже).
51
51
 
52
- Одно окружение не приковывает: у каждого инструмента, обращающегося к платформе,
52
+ Одним окружением дело не ограничено: у каждого инструмента, обращающегося к платформе,
53
53
  есть необязательный `env_file` - путь к `.env` другого стенда. Так один сервер
54
54
  работает и с облаком, и с локальной установкой, без перезапуска с другими
55
55
  реквизитами. `list_apps` по умолчанию отдаёт краткие карточки (id, имя, статус,
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
  [project]
8
8
  name = "elemctl"
9
9
  dynamic = ["version"]
10
- description = "CLI, MCP server and library for the Console API v2 of the 1C:Enterprise.Element platform (1cmycloud)"
10
+ description = "CLI, MCP server and library for the Console API v2 of the 1C:Enterprise.Element platform (1cmycloud): applications, builds from source, one-command deploy with verification, a compile probe"
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.10"
13
13
  license = "MIT"
@@ -18,7 +18,7 @@ from .errors import (
18
18
  TransportError,
19
19
  )
20
20
 
21
- __version__ = "0.32.2"
21
+ __version__ = "0.32.3"
22
22
 
23
23
  __all__ = [
24
24
  "ApiError",
@@ -538,7 +538,7 @@ def read_assembly_project(path):
538
538
  The manifest carries the technical pair the platform recognizes a project by
539
539
  (vendor plus name), and the project descriptor inside the archive carries the
540
540
  presentation - the name a console shows. The two are different things: a
541
- project named `site` is shown as "1C:Fresh Site", and comparing one against
541
+ project named `crm` is shown as "Acme CRM", and comparing one against
542
542
  the other calls every correct upload a mismatch.
543
543
 
544
544
  Light, like read_assembly_manifest: two entries are read, nothing is walked.
@@ -404,7 +404,7 @@ def cmd_projects_delete(args):
404
404
  def cmd_builds_list(args):
405
405
  """The project's assemblies, newest first and limited by default.
406
406
 
407
- The site project alone holds over a thousand assemblies: printing them all
407
+ A long-lived project alone holds over a thousand assemblies: printing them all
408
408
  made the answer to "which commit is the applied build from" a matter of
409
409
  piping through head and hoping the right card made the cut. The default
410
410
  shows the latest ten; --limit 0 brings the whole list back, and the cut is
@@ -467,8 +467,8 @@ def _upload_name_mismatch(client, project_id, file_path):
467
467
 
468
468
  Compared is what the console actually shows against what this archive would put
469
469
  there - the PRESENTATION of its project descriptor. The technical name of the
470
- manifest is a different thing: a project named `site` is shown as "1C:Fresh
471
- Site", and comparing those two called every correct upload a rename and refused
470
+ manifest is a different thing: a project named `crm` is shown as "Acme CRM",
471
+ and comparing those two called every correct upload a rename and refused
472
472
  it. The manifest name answers only when the archive carries no descriptor.
473
473
  """
474
474
  try:
@@ -61,7 +61,7 @@ INSTRUCTIONS = (
61
61
  "ensure_app, delete_app и merge_branch выполняются минутами и синхронно блокируют вызов "
62
62
  "до конца – в чате это выглядит зависанием без вывода. Такие операции "
63
63
  "запускать CLI-командой elemctl фоновым процессом (у агента – механизм "
64
- "фонового запуска вроде run_in_background, результат придёт нотификацией), а "
64
+ "фонового запуска вроде run_in_background, результат придёт уведомлением), а "
65
65
  "не синхронным вызовом MCP-инструмента; сами MCP-инструменты предпочтительны "
66
66
  "для быстрых операций чтения (list/get/find/list-builds/verify-deploy). "
67
67
  "Окружение: по умолчанию используется то, с которым запущен сервер; чтобы "
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elemctl
3
- Version: 0.32.2
4
- Summary: CLI, MCP server and library for the Console API v2 of the 1C:Enterprise.Element platform (1cmycloud)
3
+ Version: 0.32.3
4
+ Summary: CLI, MCP server and library for the Console API v2 of the 1C:Enterprise.Element platform (1cmycloud): applications, builds from source, one-command deploy with verification, a compile probe
5
5
  Author: KeyFire
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/keyfire/elemctl
@@ -38,9 +38,9 @@ Dynamic: license-file
38
38
 
39
39
  A command-line tool, MCP server and Python library for managing applications on the **1C:Enterprise.Element** cloud platform (1cmycloud.com) through Console API v2.
40
40
 
41
- elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
41
+ elemctl covers an application's lifecycle on the platform without the web console: create an application, build a `.xasm`/`.xlib` build archive from project sources, upload the build, apply it to the application and make sure the apply actually happened (the platform can silently roll back), check compilation with a probe that never touches the working application, and manage development-environment branches, dumps and the technology version. The same engine is available in three ways: the `elemctl` command for the terminal and CI, an MCP server for AI agents (Claude Code and other MCP clients), and the `elemctl` Python module for your own scripts.
42
42
 
43
- *elemctl is a CLI tool, MCP server and Python library for the 1C:Enterprise.Element (1cmycloud) Console API: manage applications, upload builds and deploy with honest apply verification. The CLI output is plain JSON.*
43
+ *elemctl is a CLI tool, MCP server and Python library for the 1C:Enterprise.Element (1cmycloud) Console API: manage applications, upload builds, deploy with honest apply verification and check compilation with a probe. The CLI output is plain JSON.*
44
44
 
45
45
  Development notes and updates (in Russian): the [1C × AI: engineering workshop](https://t.me/ceh_1c_ai) Telegram channel.
46
46
 
@@ -133,3 +133,39 @@ def test_guard_notices_a_broken_raw_link_in_the_readme(guard, monkeypatch):
133
133
  lambda name: original(name) + f"\n![gone]({guard._RAW_PREFIX}docs/renamed.png)\n",
134
134
  )
135
135
  assert any("renamed.png" in problem for problem in guard.check())
136
+
137
+
138
+ def test_guard_notices_a_feature_missing_from_one_annotation(guard, monkeypatch):
139
+ # the failure this check exists for: the block on the page names a capability and the
140
+ # one-liners around it - which is what a search engine and an AI answer quote - do not
141
+ surfaces = guard.pitch_surfaces()
142
+ surfaces["ru"]["docs/index.ru.md"] = surfaces["ru"]["docs/index.ru.md"].replace("пробник", "")
143
+ monkeypatch.setattr(guard, "pitch_surfaces", lambda: surfaces)
144
+ problems = guard.pitch_problems()
145
+ assert len(problems) == 1
146
+ assert "docs/index.ru.md" in problems[0]
147
+
148
+
149
+ def test_guard_notices_a_headline_no_row_names(guard, monkeypatch):
150
+ original = guard.box_headlines
151
+ monkeypatch.setattr(
152
+ guard, "box_headlines",
153
+ lambda name, heading: original(name, heading) + ["Invented feature"],
154
+ )
155
+ assert any("Invented feature" in problem for problem in guard.pitch_problems())
156
+
157
+
158
+ def test_guard_notices_a_row_the_page_dropped(guard, monkeypatch):
159
+ original = guard.box_headlines
160
+ monkeypatch.setattr(
161
+ guard, "box_headlines",
162
+ lambda name, heading: [h for h in original(name, heading) if h not in ("Dumps", "Дампы")],
163
+ )
164
+ assert any("Dumps" in problem for problem in guard.pitch_problems())
165
+
166
+
167
+ def test_the_annotations_are_read_as_annotations(guard):
168
+ # an extractor quietly returning a whole file would make every word check above vacuous
169
+ for locale, group in guard.pitch_surfaces().items():
170
+ for where, text in group.items():
171
+ assert 80 < len(text) < 600, f"{locale} {where}: {len(text)} characters"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes