docx-cli 0.1.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 (67) hide show
  1. docx_cli-0.1.0/.gitattributes +3 -0
  2. docx_cli-0.1.0/.gitignore +9 -0
  3. docx_cli-0.1.0/CHANGELOG.md +9 -0
  4. docx_cli-0.1.0/CONTRIBUTING.md +22 -0
  5. docx_cli-0.1.0/LICENSE +199 -0
  6. docx_cli-0.1.0/NOTICE +1 -0
  7. docx_cli-0.1.0/PKG-INFO +95 -0
  8. docx_cli-0.1.0/README.md +81 -0
  9. docx_cli-0.1.0/README.ru.md +64 -0
  10. docx_cli-0.1.0/SECURITY.md +4 -0
  11. docx_cli-0.1.0/SPEC.md +140 -0
  12. docx_cli-0.1.0/assets/flags/gb.svg +1 -0
  13. docx_cli-0.1.0/assets/flags/ru.svg +1 -0
  14. docx_cli-0.1.0/assets/poster.jpg +0 -0
  15. docx_cli-0.1.0/docs/design/nested-lists-tables.md +106 -0
  16. docx_cli-0.1.0/docs/vault/ARCHITECTURE.md +68 -0
  17. docx_cli-0.1.0/docs/vault/LIMITATIONS.md +23 -0
  18. docx_cli-0.1.0/docs/vault/USAGE.md +120 -0
  19. docx_cli-0.1.0/docx_cli/__init__.py +8 -0
  20. docx_cli-0.1.0/docx_cli/__main__.py +7 -0
  21. docx_cli-0.1.0/docx_cli/agent_reader.py +87 -0
  22. docx_cli-0.1.0/docx_cli/blocks.py +333 -0
  23. docx_cli-0.1.0/docx_cli/builder.py +116 -0
  24. docx_cli-0.1.0/docx_cli/cli.py +641 -0
  25. docx_cli-0.1.0/docx_cli/errors.py +21 -0
  26. docx_cli-0.1.0/docx_cli/fonts_normalize.py +119 -0
  27. docx_cli-0.1.0/docx_cli/inject_scan.py +369 -0
  28. docx_cli-0.1.0/docx_cli/mcp_server.py +380 -0
  29. docx_cli-0.1.0/docx_cli/md_court.py +665 -0
  30. docx_cli-0.1.0/docx_cli/profiles.py +272 -0
  31. docx_cli-0.1.0/docx_cli/spec.py +233 -0
  32. docx_cli-0.1.0/docx_cli/validate.py +786 -0
  33. docx_cli-0.1.0/examples/spec_example.json +70 -0
  34. docx_cli-0.1.0/pyproject.toml +31 -0
  35. docx_cli-0.1.0/templates/hodatajstvo.json +60 -0
  36. docx_cli-0.1.0/templates/iskovoe_zayavlenie.json +75 -0
  37. docx_cli-0.1.0/templates/otzyv_na_isk.json +69 -0
  38. docx_cli-0.1.0/templates/soyu_rayon.json +61 -0
  39. docx_cli-0.1.0/templates/vs_sud.json +65 -0
  40. docx_cli-0.1.0/tests/conftest.py +65 -0
  41. docx_cli-0.1.0/tests/fixtures/v0100_legacy_md.json +784 -0
  42. docx_cli-0.1.0/tests/fixtures/v053_repro.md +19 -0
  43. docx_cli-0.1.0/tests/test_builder.py +368 -0
  44. docx_cli-0.1.0/tests/test_cli.py +144 -0
  45. docx_cli-0.1.0/tests/test_court.py +419 -0
  46. docx_cli-0.1.0/tests/test_inject_scan.py +95 -0
  47. docx_cli-0.1.0/tests/test_spec.py +148 -0
  48. docx_cli-0.1.0/tests/test_v0100_mcp.py +243 -0
  49. docx_cli-0.1.0/tests/test_v0100_nested_lists_tables.py +481 -0
  50. docx_cli-0.1.0/tests/test_v0100_profiles.py +148 -0
  51. docx_cli-0.1.0/tests/test_v0100_release_meta.py +62 -0
  52. docx_cli-0.1.0/tests/test_v040.py +120 -0
  53. docx_cli-0.1.0/tests/test_v050.py +128 -0
  54. docx_cli-0.1.0/tests/test_v051.py +168 -0
  55. docx_cli-0.1.0/tests/test_v052.py +94 -0
  56. docx_cli-0.1.0/tests/test_v053.py +364 -0
  57. docx_cli-0.1.0/tests/test_v060_normalize.py +107 -0
  58. docx_cli-0.1.0/tests/test_v060_scan_vectors.py +292 -0
  59. docx_cli-0.1.0/tests/test_v070_lists.py +39 -0
  60. docx_cli-0.1.0/tests/test_v070_md.py +76 -0
  61. docx_cli-0.1.0/tests/test_v070_profile.py +117 -0
  62. docx_cli-0.1.0/tests/test_v070_title.py +53 -0
  63. docx_cli-0.1.0/tests/test_v070_validate.py +110 -0
  64. docx_cli-0.1.0/tests/test_v070_verify.py +67 -0
  65. docx_cli-0.1.0/tests/test_v080_control_pins.py +145 -0
  66. docx_cli-0.1.0/tests/test_v090_control_pins.py +104 -0
  67. docx_cli-0.1.0/tests/test_validate.py +273 -0
@@ -0,0 +1,3 @@
1
+ # Захваченные страницы-фикстуры и генерируемые HTML-примеры — тестовые данные, не код проекта.
2
+ *.html linguist-vendored
3
+ *.htm linguist-vendored
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .pytest_cache/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .state/
9
+ *.bak
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - First public release: deterministic .docx builder from JSON specs and Markdown,
6
+ layout validation against gost/court profiles, `mcp` mode (8 tools), nested lists
7
+ and pipe tables (B-10), Supreme Court and SOYU layout profiles (T-05), injection
8
+ scanner for incoming text, write-guard: mutating tools answer `needs_confirmation`
9
+ until confirmed.
@@ -0,0 +1,22 @@
1
+ # CONTRIBUTING — docx-cli
2
+
3
+ ## Process
4
+ 1. Issue/задача с вектором воспроизведения (для изменений сканера/валидатора — синтетический
5
+ docx или spec-минимум, живые документы дел — никогда).
6
+ 2. Тест сначала (RED) с ссылкой наFinding-номер, реализация (GREEN).
7
+ 3. `python -m pytest -q -o addopts=''` — зелёный; старые тесты не редактируются без
8
+ обоснования в PR (история контрактов пинится).
9
+ 4. Envelope-вывод CLI — стабильный JSON; exit-коды: 0 ok / 1 бизнес-отказ / 2 usage.
10
+ 5. DCO: коммит с `Signed-off-by:` — вклад передаётся под Apache-2.0 (патент-грант включительно);
11
+ отправляя patch, вы подтверждаете права на него и согласны с лицензией репозитория.
12
+
13
+ ## Release discipline
14
+ - Именованный артефакт релиза не перезаписывается; новая версия — новые dist-файлы + SHA256SUMS +
15
+ detached GPG-подпись release-ключом; `doctor --verify-signature` обязан быть ok до анонса.
16
+ - Изменения сканера безопасности требуют прогона векторного набора (tests/test_v0*_*.py)
17
+ и свежей установки в чистом venv из allowlist-архива.
18
+ - docx bus-free: пакет не должен вызывать шину/a2a/сеть; интеграция — только печатью готовых команд.
19
+
20
+ ## What we don't take
21
+ - Юридические заключения/дисклеймеры в код (контент — зона правоприменителя).
22
+ - Фикстуры с реальными сторонами, номерами дел, ПДн.
docx_cli-0.1.0/LICENSE ADDED
@@ -0,0 +1,199 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or entity on
63
+ behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or Derivative
95
+ Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text file from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for ensuring that
150
+ any use you make of this software complies with the laws and
151
+ regulations of your jurisdiction.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to you for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any kind arising as a
159
+ result of this License or out of the use or performance of the
160
+ Work (even if such Contributor has been advised of the possibility
161
+ of such damages).
162
+
163
+ 9. Accepting Warranty or Additional Liability. While redistributing
164
+ the Work or Derivative Works thereof, You may choose to offer, and
165
+ charge a fee for, acceptance of support, warranty, indemnity, or
166
+ other liability obligations and/or rights consistent with this
167
+ License. However, in accepting such obligations, You may act only
168
+ on Your own behalf and on Your own responsibility, not on behalf
169
+ of any other Contributor, and only if You agree to indemnify,
170
+ defend, and hold each Contributor harmless for any liability
171
+ incurred by, or claims asserted against, such Contributor by reason
172
+ of your accepting any such warranty or additional liability.
173
+
174
+ END OF TERMS AND CONDITIONS
175
+
176
+ APPENDIX: How to apply the Apache License to your work.
177
+
178
+ To apply the Apache License to your work, attach the following
179
+ boilerplate notice, with the fields enclosed by brackets "[]"
180
+ replaced with your own identifying information. (Don't include
181
+ the brackets!) The text should be enclosed in the appropriate
182
+ comment syntax for the file format. We also recommend that a
183
+ file or class name and description of purpose be included on the
184
+ same "printed page" as the copyright notice for easier
185
+ identification within third-party archives.
186
+
187
+ Copyright [yyyy] [name of copyright owner]
188
+
189
+ Licensed under the Apache License, Version 2.0 (the "License");
190
+ you may not use this file except in compliance with the License.
191
+ You may obtain a copy of the License at
192
+
193
+ http://www.apache.org/licenses/LICENSE-2.0
194
+
195
+ Unless required by applicable law or agreed to in writing, software
196
+ distributed under the License is distributed on an "AS IS" BASIS,
197
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
198
+ implied. See the License for the specific language governing
199
+ permissions and limitations under the License.
docx_cli-0.1.0/NOTICE ADDED
@@ -0,0 +1 @@
1
+ docx-cli — Copyright (C) 2026 lnfnt <lnfnt@proton.me>. License: Apache-2.0.
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.5
2
+ Name: docx-cli
3
+ Version: 0.1.0
4
+ Summary: Deterministic .docx generation, reverse validation and injection scanning for Russian legal documents
5
+ Author-email: lnfnt <lnfnt@proton.me>
6
+ License: Apache-2.0
7
+ License-File: LICENSE
8
+ License-File: NOTICE
9
+ Requires-Python: >=3.11
10
+ Requires-Dist: lxml>=4.9.0
11
+ Requires-Dist: pydantic>=2.0.0
12
+ Requires-Dist: python-docx>=1.1.0
13
+ Description-Content-Type: text/markdown
14
+
15
+ # docx-cli
16
+
17
+ ![license](https://img.shields.io/badge/license-Apache--2.0-blue) ![python](https://img.shields.io/badge/python-3.11%2B-green) ![release](https://img.shields.io/badge/release-v0.1.0-informational) ![MCP](https://img.shields.io/badge/MCP-8%20tools-brightgreen) ![artifacts](https://img.shields.io/badge/artifacts-GPG--signed-green)
18
+
19
+
20
+ <p align="center"><img src="assets/poster.jpg" width="820" alt="docx-cli poster"></p>
21
+
22
+ Deterministic generator of Russian-language legal `.docx` documents. Builds from a
23
+ machine-checkable JSON spec (or Markdown for procedural filings), then re-opens the written
24
+ file and validates layout against the standard — margins, font, spacing, indents, list
25
+ numbering, dashes, «ё». Any mismatch is fail-closed: the partial file is removed and an
26
+ error envelope is returned. Includes an injection scanner for incoming text and an MCP mode.
27
+
28
+ [<img src="assets/flags/ru.svg" height="16" align="top" alt="RU"> Русский](README.ru.md) · **English**
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install git+https://github.com/lnfnt/docx-cli.git
34
+ docx-cli doctor
35
+ ```
36
+
37
+ Not on PyPI. Checkout: `git clone https://github.com/lnfnt/docx-cli.git && cd docx-cli
38
+ && python3 -m venv .venv && . .venv/bin/activate && pip install -e .` (or `pipx install .`).
39
+ Python >= 3.11; deps: python-docx, pydantic, lxml. No network calls.
40
+
41
+ ## Quickstart
42
+
43
+ ```bash
44
+ docx-cli build examples/spec_example.json output.docx
45
+ docx-cli validate output.docx
46
+ docx-cli doctor
47
+ ```
48
+
49
+ One JSON envelope per command; exit codes: 0 ok, 1 business rejection, 2 usage/structural
50
+ error (incl. strict warnings).
51
+
52
+ ## Layout standard
53
+
54
+ | Setting | gost (default) | court profile |
55
+ |---|---|---|
56
+ | Page/margins | A4; L 3.0 / R 1.5 / T 2.0 / B 2.0 cm | same geometry |
57
+ | Font | Times New Roman 12 pt (headings 14) | Times New Roman 14 pt |
58
+ | Spacing | 1.5 (header/title 1.15) | 1.0 |
59
+ | Indents | 1.25 cm first line; body justified | header `left_indent = 7.0 cm`, hanging lists |
60
+
61
+ `vs_sud` (Supreme Court) and `soyu_rayon` (first-instance SOYU incl. justice-of-the-peace
62
+ slot) are formatting skeletons: geometry plus `{...}` placeholders, no normative content;
63
+ templates in `templates/vs_sud.json`, `templates/soyu_rayon.json`. Full contract: `SPEC.md`.
64
+
65
+ ## MCP mode
66
+
67
+ ```bash
68
+ docx-cli mcp # JSON-RPC 2.0 on stdin/stdout
69
+ docx-cli mcp --tools # tools/list dump
70
+ ```
71
+
72
+ Eight tools: `docx_build`, `docx_validate`, `docx_scan`, `docx_normalize`, `docx_md_build`,
73
+ `docx_doctor`, `docx_agent_read`, `docx_verify_forbidden`. Write tools require `confirm:
74
+ true`; otherwise `status=needs_confirmation` and nothing is written. Malformed transport
75
+ lines return a `-32700` envelope without crashing.
76
+
77
+ ## md-converter
78
+
79
+ Nested lists of depth 1-4 (`List Bullet/Number 2-3`; depth >4 skipped with a
80
+ `list_depth_gt4` marker in the report); GFM pipe tables (`Table Grid`, alignments, repeated
81
+ headers, inline formatting in cells, `\|` escaping); block constructs inside cells are
82
+ unsupported and flagged (`block_in_cell`). Legacy md converts structurally identically to
83
+ v0.9.0.
84
+
85
+ ## Limits
86
+
87
+ - Not legal advice; does not validate case facts.
88
+ - Generation from spec/Markdown only — not an editor for foreign legacy .docx files.
89
+ - vs_sud/soyu_rayon carry formatting, not norms; normative content comes from your spec.
90
+
91
+ ## License
92
+
93
+ Apache-2.0 (`LICENSE`). Verify: `sha256sum -c SHA256SUMS`, `gpg --verify *.asc` (key attached).
94
+
95
+ Author and copyright holder: [lnfnt](mailto:lnfnt@proton.me).
@@ -0,0 +1,81 @@
1
+ # docx-cli
2
+
3
+ ![license](https://img.shields.io/badge/license-Apache--2.0-blue) ![python](https://img.shields.io/badge/python-3.11%2B-green) ![release](https://img.shields.io/badge/release-v0.1.0-informational) ![MCP](https://img.shields.io/badge/MCP-8%20tools-brightgreen) ![artifacts](https://img.shields.io/badge/artifacts-GPG--signed-green)
4
+
5
+
6
+ <p align="center"><img src="assets/poster.jpg" width="820" alt="docx-cli poster"></p>
7
+
8
+ Deterministic generator of Russian-language legal `.docx` documents. Builds from a
9
+ machine-checkable JSON spec (or Markdown for procedural filings), then re-opens the written
10
+ file and validates layout against the standard — margins, font, spacing, indents, list
11
+ numbering, dashes, «ё». Any mismatch is fail-closed: the partial file is removed and an
12
+ error envelope is returned. Includes an injection scanner for incoming text and an MCP mode.
13
+
14
+ [<img src="assets/flags/ru.svg" height="16" align="top" alt="RU"> Русский](README.ru.md) · **English**
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ pip install git+https://github.com/lnfnt/docx-cli.git
20
+ docx-cli doctor
21
+ ```
22
+
23
+ Not on PyPI. Checkout: `git clone https://github.com/lnfnt/docx-cli.git && cd docx-cli
24
+ && python3 -m venv .venv && . .venv/bin/activate && pip install -e .` (or `pipx install .`).
25
+ Python >= 3.11; deps: python-docx, pydantic, lxml. No network calls.
26
+
27
+ ## Quickstart
28
+
29
+ ```bash
30
+ docx-cli build examples/spec_example.json output.docx
31
+ docx-cli validate output.docx
32
+ docx-cli doctor
33
+ ```
34
+
35
+ One JSON envelope per command; exit codes: 0 ok, 1 business rejection, 2 usage/structural
36
+ error (incl. strict warnings).
37
+
38
+ ## Layout standard
39
+
40
+ | Setting | gost (default) | court profile |
41
+ |---|---|---|
42
+ | Page/margins | A4; L 3.0 / R 1.5 / T 2.0 / B 2.0 cm | same geometry |
43
+ | Font | Times New Roman 12 pt (headings 14) | Times New Roman 14 pt |
44
+ | Spacing | 1.5 (header/title 1.15) | 1.0 |
45
+ | Indents | 1.25 cm first line; body justified | header `left_indent = 7.0 cm`, hanging lists |
46
+
47
+ `vs_sud` (Supreme Court) and `soyu_rayon` (first-instance SOYU incl. justice-of-the-peace
48
+ slot) are formatting skeletons: geometry plus `{...}` placeholders, no normative content;
49
+ templates in `templates/vs_sud.json`, `templates/soyu_rayon.json`. Full contract: `SPEC.md`.
50
+
51
+ ## MCP mode
52
+
53
+ ```bash
54
+ docx-cli mcp # JSON-RPC 2.0 on stdin/stdout
55
+ docx-cli mcp --tools # tools/list dump
56
+ ```
57
+
58
+ Eight tools: `docx_build`, `docx_validate`, `docx_scan`, `docx_normalize`, `docx_md_build`,
59
+ `docx_doctor`, `docx_agent_read`, `docx_verify_forbidden`. Write tools require `confirm:
60
+ true`; otherwise `status=needs_confirmation` and nothing is written. Malformed transport
61
+ lines return a `-32700` envelope without crashing.
62
+
63
+ ## md-converter
64
+
65
+ Nested lists of depth 1-4 (`List Bullet/Number 2-3`; depth >4 skipped with a
66
+ `list_depth_gt4` marker in the report); GFM pipe tables (`Table Grid`, alignments, repeated
67
+ headers, inline formatting in cells, `\|` escaping); block constructs inside cells are
68
+ unsupported and flagged (`block_in_cell`). Legacy md converts structurally identically to
69
+ v0.9.0.
70
+
71
+ ## Limits
72
+
73
+ - Not legal advice; does not validate case facts.
74
+ - Generation from spec/Markdown only — not an editor for foreign legacy .docx files.
75
+ - vs_sud/soyu_rayon carry formatting, not norms; normative content comes from your spec.
76
+
77
+ ## License
78
+
79
+ Apache-2.0 (`LICENSE`). Verify: `sha256sum -c SHA256SUMS`, `gpg --verify *.asc` (key attached).
80
+
81
+ Author and copyright holder: [lnfnt](mailto:lnfnt@proton.me).
@@ -0,0 +1,64 @@
1
+ # docx-cli
2
+
3
+ **Русский** · [<img src="assets/flags/gb.svg" height="16" align="top" alt="EN"> English](README.md)
4
+
5
+ ![license](https://img.shields.io/badge/license-Apache--2.0-blue) ![python](https://img.shields.io/badge/python-3.11%2B-green) ![release](https://img.shields.io/badge/release-v0.1.0-informational) ![MCP](https://img.shields.io/badge/MCP-8%20tools-brightgreen)
6
+
7
+ <p align="center"><img src="assets/poster.jpg" width="820" alt="docx-cli poster"></p>
8
+
9
+ *Основной README — английский ([README.md](README.md)); это русская версия.*
10
+
11
+ Детерминированный генератор русскоязычных юридических документов `.docx`. Сборка из
12
+ машиночитаемого JSON-спека (или Markdown для процессуальных актов), затем повторное открытие
13
+ записанного файла и обратная валидация вёрстки: поля, шрифт, интервалы, отступы, нумерация,
14
+ типографика, «ё». Расхождение — fail-closed: частичный файл удаляется, CLI возвращает
15
+ ошибочный JSON-конверт. Встроен сканер скрытых инъекций входящего текста и MCP-режим.
16
+
17
+ ## Установка
18
+
19
+ ```bash
20
+ pip install git+https://github.com/lnfnt/docx-cli.git
21
+ docx-cli doctor
22
+ ```
23
+
24
+ На PyPI пакета нет. Checkout: `pip install -e .` или `pipx install .` (Python >= 3.11;
25
+ python-docx, pydantic, lxml). Сетевых вызовов нет.
26
+
27
+ ## Быстрый старт
28
+
29
+ ```bash
30
+ docx-cli build examples/spec_example.json output.docx
31
+ docx-cli validate output.docx
32
+ docx-cli doctor
33
+ ```
34
+
35
+ Единый JSON-конверт; коды выхода: 0 ок, 1 бизнес-отказ, 2 usage/структурная ошибка.
36
+
37
+ ## Стандарт оформления
38
+
39
+ A4; поля Л=3.0/П=1.5/В=2.0/Н=2.0 см; Times New Roman 12 pt (заголовки 14); интервал 1.5;
40
+ красная строка 1.25 см. Профиль `court`: 14 pt везде, интервал 1.0, шапка
41
+ `left_indent = 7.0 см`, висячие списки. Скелеты `vs_sud` и `soyu_rayon` — геометрия и
42
+ плейсхолдеры `{...}` без норм; шаблоны в `templates/`. Полный контракт — `SPEC.md`.
43
+
44
+ ## MCP-режим
45
+
46
+ `docx-cli mcp` — JSON-RPC 2.0, восемь инструментов. Write-инструменты требуют `confirm:
47
+ true`, иначе возвращается `needs_confirmation` без записей.
48
+
49
+ ## Конвертер md
50
+
51
+ Вложенные списки 1-4 (глубина >4 маркируется `list_depth_gt4`), GFM-таблицы с выравниваниями
52
+ и inline-форматированием в ячейках; блочные конструкции в ячейках помечаются `block_in_cell`.
53
+
54
+ ## Ограничения
55
+
56
+ - Не юридический совет, факты дела не проверяются.
57
+ - Только генерация из спека/Markdown; чужие legacy .docx не редактирует.
58
+ - Профильные скелеты содержат вёрстку, нормы — в спеке юриста.
59
+
60
+ ## Лицензия
61
+
62
+ Apache-2.0 (`LICENSE`). Проверка: `sha256sum -c SHA256SUMS`, `gpg --verify *.asc`.
63
+
64
+ Автор и правообладатель: [lnfnt](mailto:lnfnt@proton.me).
@@ -0,0 +1,4 @@
1
+ # Security Policy
2
+
3
+ Report vulnerabilities privately to <lnfnt@proton.me>.
4
+ We aim to acknowledge within 5 business days and ship a fix before public disclosure.
docx_cli-0.1.0/SPEC.md ADDED
@@ -0,0 +1,140 @@
1
+ # SPEC — docx-cli v0.9.0
2
+
3
+ **Статус:** реализовано и принято (v0.9.0, акт приёмки 24.10.2026).
4
+ **Принципы:** fail-closed, production-grade, без костылей, машинный контракт для ИИ-агентов, полная документация без взгляда в код.
5
+
6
+ ## 1. Назначение
7
+
8
+ `docx-cli` — локальный CLI/Python-пакет для детерминированной генерации русскоязычных юридических документов в формате .docx (процессуальные документы, ответы в госорганы, письма, правовые анализы).
9
+
10
+ **Целевая аудитория:** практикующие юристы и ИИ-агенты, вызывающие генерацию из автоматизированных пайплайнов.
11
+
12
+ **Проблема, которую решает:** генерация документов обычно остаётся одноразовыми скриптами с дублированной логикой. Каждый новый документ = новый скрипт с копипастой. Документы меняются — скрипты разъезжаются со стандартом.
13
+
14
+ ## 2. Что НЕ входит (границы)
15
+
16
+ - НЕ валидирует юридическое содержание и не проверяет нормы права (это задача правоприменителя).
17
+ - НЕ парсит PDF/сканы.
18
+ - НЕ рендерит в PDF (может проверить наличие LibreOffice через doctor, но не конвертирует).
19
+ - НЕ придумывает факты: вход — только то, что дал вызывающий. Пробелы — плейсхолдеры `[УКАЗАТЬ ...]`, не тишина.
20
+ - НЕ редактирует существующие .docx (только генерация с нуля; произвольное редактирование — вне объёма).
21
+
22
+ ## 3. Стандарт оформления (единственный, зашит по умолчанию)
23
+
24
+ Источник истины: внутренний стандарт оформления (ГОСТ-юридический дефолт):
25
+
26
+ | Параметр | Значение по умолчанию |
27
+ |---|---|
28
+ | Бумага | A4 (не Letter) |
29
+ | Поля | L=3.0, R=1.5, T=2.0, B=2.0 см |
30
+ | Шрифт | Times New Roman, 12 pt (заголовки 14 pt) |
31
+ | Межстрочный | 1.5 (шапка/титул 1.15) |
32
+ | Абзацный отступ | 1.25 см |
33
+ | Выравнивание тела | justified |
34
+ | Ё | запрещена в тексте, кроме официальных реквизитов (паспорт, СНИЛС, юр-реквизиты) — валидатор предупреждает |
35
+ | Тире | только «—» или «-», en-dash «–» запрещён — валидатор исправляет/предупреждает |
36
+
37
+ Профиль документа переопределяет параметры, но дефолт один — ГОСТ-юридический.
38
+
39
+ ### 3.1 Профиль `court`
40
+
41
+ Профиль `court` предназначен для процессуальных документов (арбитраж, суды общей юрисдикции, надзорные органы):
42
+
43
+ | Параметр | Значение |
44
+ |---|---|
45
+ | Шрифт | Times New Roman, **14 pt** для всего документа (шапка, заголовок, тело, списки, таблицы, подпись) |
46
+ | Межстрочный интервал | 1.0 (допустимо переопределить на 1.15 через `line_spacing`) |
47
+ | Поля | Л=3.0, П=1.5, В=2.0, Н=2.0 см |
48
+ | Абзацный отступ | 1.25 см |
49
+ | Шапка | блок с `left_indent = 7.0 см` (допустимый диапазон 6.0–8.0), выравнивание строк LEFT |
50
+ | Заголовок | CENTER, Bold, 14 pt, `space_before/after = 12 pt` |
51
+ | Маркер «ПРОШУ» | отдельный блок `pleading_marker`: CENTER, Bold, 14 pt, без абзацного отступа |
52
+ | Списки | висячий отступ: `left_indent = 1.25 см`, `first_line_indent = -0.75 см` |
53
+ | Подпись | текстовый формат (без таблицы) по умолчанию; допустим явный `format: "table"` |
54
+
55
+ ## 4. Архитектура
56
+
57
+ ```
58
+ docx_cli/
59
+ __init__.py # публичный API: build_document, DocSpec
60
+ __main__.py # python -m docx_cli
61
+ cli.py # argparse CLI: build, validate, doctor
62
+ spec.py # DocSpec (pydantic): профиль документа, стороны, блоки
63
+ builder.py # ядро генерации (python-docx), стили, блоки
64
+ blocks.py # типы блоков: header, title, body, table,
65
+ # numbered_list, signature_block, attachments_list
66
+ validate.py # встроенный валидатор результата (порт docx_validate.py
67
+ # + ГОСТ-проверки: поля, шрифт, интервал, отступ, ё, en-dash)
68
+ errors.py # SpecError, BuildError, ValidationError (fail-closed)
69
+ models.json example:
70
+ см. examples/spec_example.json
71
+ ```
72
+
73
+ ## 5. Машинный контракт
74
+
75
+ ### 5.1 CLI
76
+
77
+ ```
78
+ docx-cli build <spec.json> <output.docx> [--profile gost|compact|court]
79
+ docx-cli validate <file.docx> [--json] # exit 0=ok, 1=errors, 2=warnings only w/ --strict
80
+ docx-cli doctor # env: python-docx, lxml, права записи
81
+ ```
82
+
83
+ Все команды выводят JSON-конверт:
84
+ ```json
85
+ {"ok": true, "status": "ok", "reason": null, "parsed_at": "...", "data": {...}, "metadata": {...}}
86
+ ```
87
+
88
+ ### 5.2 Spec (JSON, pydantic-валидация)
89
+
90
+ ```json
91
+ {
92
+ "profile": "gost",
93
+ "output": {"file_name": "2026.09.22.Отзыв_истца.docx", "author": "Иванов И.И."},
94
+ "header": {"align": "right", "lines": ["В ... суд", "Истец: ..."]},
95
+ "title": {"main": "ОТЗЫВ ИСТЦА", "subtitle": "на возражения ответчика"},
96
+ "body": [
97
+ {"type": "paragraph", "text": "..." , "inline_markdown": true},
98
+ {"type": "numbered_list", "items": ["..."]},
99
+ {"type": "table", "headers": [...], "rows": [[...]], "widths_cm": [...]},
100
+ {"type": "pleading_marker", "text": "ПРОШУ СУД:"},
101
+ {"type": "signature_block", "left": "Представитель", "right": "___________ /Иванов И.И./", "format": "table"},
102
+ {"type": "attachments_list", "items": ["1. Копия ... на N л."]}
103
+ ],
104
+
105
+ "checks": {"no_yo": true, "no_en_dash": true, "require_norms_refs": false}
106
+ }
107
+ ```
108
+
109
+ Правила spec:
110
+ - Любое нарушение схемы → SpecError, exit 1, JSON `{"ok": false, "status": "error", "reason": "spec_error: <деталь>"}`. Никаких «похожих» полей, никаких дефолтов-догадок.
111
+ - Плейсхолдеры `[УКАЗАТЬ ...]` разрешены и подсвечиваются в validate (warning `placeholder_present`), если `checks.require_norms_refs` и т.п. не запрошены жёстче.
112
+ - Если `checks.no_yo` — валидация после сборки ищет «ё» вне whitelist-реквизитов; находка → warning (не молча).
113
+
114
+ ### 5.3 Валидатор (встроенный, всегда после сборки)
115
+
116
+ Проверки результата (после генерации builder сам себе валидирует файл):
117
+ 1. Пакет открывается, части на месте, связи резолвятся (порт docx_validate.py).
118
+ 2. Поля секции = профилю (±0.05 см).
119
+ 3. Все run'ы: Times New Roman; размер тела/заголовков по профилю.
120
+ 4. Межстрочный интервал тела = 1.5.
121
+ 5. Абзацный отступ тела = 1.25 см.
122
+ 6. Нет en-dash; при checks.no_yo — нет «ё» вне реквизитов.
123
+ 7. Нумерация в numbered_list последовательная (1,2,3 без пропусков).
124
+
125
+ Результат в metadata: `{"checks": {"margins": "pass", "fonts": "pass", ...}, "warnings": [...]}`. Любая error-находка = exit 1 и файл НЕ считается готовым (builder удаляет частичный вывод).
126
+
127
+ ## 6. Требования к реализации
128
+
129
+ 1. Python 3.11+, зависимости: python-docx, pydantic, lxml.
130
+ 2. Тесты pytest: ≥ 60, каждый ГОСТ-параметр покрыт тестом на реальном сгенерированном файле (читаем обратно docx и проверяем XML/свойства, не «на слово»).
131
+ 3. Пример: `examples/spec_example.json` + golden-тест (собранный файл сравнивается по структурным признакам).
132
+ 4. Документация: README.md, SPEC.md (этот файл), docs/{USAGE,ARCHITECTURE,LIMITATIONS}.md — человекочитаемо, без взгляда в код.
133
+ 5. doctor проверяет: версию python, импорт пакета, наличие python-docx/lxml, права записи в cwd.
134
+
135
+ ## 7. Критерии приёмки
136
+
137
+ - `docx-cli build examples/spec_example.json out.docx` → exit 0, JSON ok:true, файл открывается, валидатор все проверки pass.
138
+ - Обратное чтение out.docx подтверждает: поля/шрифт/интервалы/отступ — по разделу 3.
139
+ - Тест-сьют зелёный; fabricating-тестов нет (все значения проверяются чтением файла).
140
+ - Старые одноразовые скрипты не трогаем — они выпадают естественно после принятия продукта.
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 40"><rect width="60" height="40" fill="#012169"/><path d="M0 0 60 40M60 0 0 40" stroke="#fff" stroke-width="9"/><path d="M0 0 60 40M60 0 0 40" stroke="#C8102E" stroke-width="4"/><path d="M30 0V40M0 20H60" stroke="#fff" stroke-width="13"/><path d="M30 0V40M0 20H60" stroke="#C8102E" stroke-width="7"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 40"><rect width="60" height="40" fill="#fff"/><rect y="13.3" width="60" height="13.4" fill="#0039A6"/><rect y="26.6" width="60" height="13.4" fill="#D52B1E"/></svg>
Binary file