python-hwpx 4.2.0__tar.gz → 5.0.1__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 (397) hide show
  1. {python_hwpx-4.2.0/src/python_hwpx.egg-info → python_hwpx-5.0.1}/PKG-INFO +57 -15
  2. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/README.md +53 -10
  3. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/pyproject.toml +54 -32
  4. python_hwpx-5.0.1/src/hwpx/__init__.py +417 -0
  5. python_hwpx-5.0.1/src/hwpx/_document/__init__.py +2 -0
  6. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/_units.py +1 -1
  7. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/fields.py +1 -1
  8. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/layout.py +1 -1
  9. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/media.py +1 -1
  10. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/memos.py +1 -1
  11. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/persistence.py +1 -1
  12. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/shapes.py +14 -3
  13. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/_document/tracked.py +53 -9
  14. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/body_patch.py +3 -3
  15. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/document.py +35 -3
  16. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/errors.py +9 -2
  17. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/form_fit/engine.py +2 -2
  18. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/form_fit/measure.py +1 -1
  19. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/opc/package.py +34 -7
  20. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/body.py +56 -0
  21. python_hwpx-5.0.1/src/hwpx/oxml/color.py +60 -0
  22. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/objects.py +140 -14
  23. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/paragraph.py +95 -4
  24. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/patch.py +22 -0
  25. python_hwpx-5.0.1/src/hwpx/quality/rendering.py +136 -0
  26. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/quality/report.py +1 -1
  27. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/quality/save_pipeline.py +12 -10
  28. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/table_patch.py +77 -15
  29. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/__init__.py +19 -63
  30. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/doc_diff.py +0 -39
  31. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/exporter.py +20 -7
  32. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/mail_merge.py +16 -12
  33. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/page_guard.py +11 -12
  34. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/read_fidelity.py +1 -1
  35. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/redline.py +81 -42
  36. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/template_analyzer.py +0 -46
  37. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/toc_author.py +1 -1
  38. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/toc_fidelity.py +45 -7
  39. {python_hwpx-4.2.0 → python_hwpx-5.0.1/src/python_hwpx.egg-info}/PKG-INFO +57 -15
  40. python_hwpx-5.0.1/src/python_hwpx.egg-info/SOURCES.txt +208 -0
  41. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/python_hwpx.egg-info/entry_points.txt +0 -2
  42. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/python_hwpx.egg-info/requires.txt +2 -3
  43. python_hwpx-5.0.1/tests/test_add_control.py +71 -0
  44. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_authoring_quality_corpus.py +11 -0
  45. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_blind_eval_fixture.py +1 -1
  46. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_corpus_read_fidelity.py +1 -1
  47. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_doc_diff.py +0 -31
  48. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_document_facade_surface.py +1 -1
  49. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_document_formatting.py +6 -2
  50. python_hwpx-5.0.1/tests/test_document_ops_runtime_boundary.py +204 -0
  51. python_hwpx-5.0.1/tests/test_documentation_code_fences.py +462 -0
  52. python_hwpx-5.0.1/tests/test_error_messages.py +57 -0
  53. python_hwpx-5.0.1/tests/test_evalplan_core_primitives.py +71 -0
  54. python_hwpx-5.0.1/tests/test_form_fill_core_primitives.py +38 -0
  55. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_form_fit.py +3 -3
  56. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_form_fit_integration.py +1 -1
  57. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_fuzz_catalog_derive_expected.py +13 -2
  58. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_fuzz_loop.py +14 -3
  59. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_fuzz_regressions.py +12 -1
  60. python_hwpx-5.0.1/tests/test_golden_api.py +286 -0
  61. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_layout_cache_scope.py +1 -1
  62. python_hwpx-5.0.1/tests/test_library_boundary_closure.py +195 -0
  63. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_mail_merge_xlsx.py +1 -3
  64. python_hwpx-5.0.1/tests/test_moved_surface_hints.py +66 -0
  65. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_mutation_report.py +1 -1
  66. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_new_features.py +76 -7
  67. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_oxml_modularization.py +12 -23
  68. python_hwpx-5.0.1/tests/test_product_boundary.py +842 -0
  69. python_hwpx-5.0.1/tests/test_public_artifact_hygiene.py +548 -0
  70. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_read_fidelity.py +1 -1
  71. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_redline_authoring.py +126 -0
  72. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_redline_verify.py +43 -15
  73. python_hwpx-5.0.1/tests/test_release_workflow_safety.py +1101 -0
  74. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_save_pipeline.py +40 -18
  75. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_section_headers.py +3 -3
  76. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_set_paragraph_format_keep.py +1 -1
  77. python_hwpx-5.0.1/tests/test_shape_geometry_contract.py +322 -0
  78. python_hwpx-5.0.1/tests/test_stable_surface.py +354 -0
  79. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_table_patch.py +4 -4
  80. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_table_patch_m105.py +2 -2
  81. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_template_analyzer_enrichment.py +4 -18
  82. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_toc_author.py +1 -1
  83. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_toc_fidelity.py +64 -19
  84. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_version_metadata.py +1 -1
  85. python_hwpx-4.2.0/src/hwpx/__init__.py +0 -272
  86. python_hwpx-4.2.0/src/hwpx/_document/__init__.py +0 -2
  87. python_hwpx-4.2.0/src/hwpx/agent/__init__.py +0 -125
  88. python_hwpx-4.2.0/src/hwpx/agent/_batch_verification.py +0 -383
  89. python_hwpx-4.2.0/src/hwpx/agent/blueprint/__init__.py +0 -58
  90. python_hwpx-4.2.0/src/hwpx/agent/blueprint/bundle.py +0 -282
  91. python_hwpx-4.2.0/src/hwpx/agent/blueprint/catalog.py +0 -136
  92. python_hwpx-4.2.0/src/hwpx/agent/blueprint/dump.py +0 -520
  93. python_hwpx-4.2.0/src/hwpx/agent/blueprint/mapping.py +0 -312
  94. python_hwpx-4.2.0/src/hwpx/agent/blueprint/model.py +0 -722
  95. python_hwpx-4.2.0/src/hwpx/agent/blueprint/native.py +0 -621
  96. python_hwpx-4.2.0/src/hwpx/agent/blueprint/replay.py +0 -622
  97. python_hwpx-4.2.0/src/hwpx/agent/catalog.py +0 -252
  98. python_hwpx-4.2.0/src/hwpx/agent/cli.py +0 -631
  99. python_hwpx-4.2.0/src/hwpx/agent/commands.py +0 -1383
  100. python_hwpx-4.2.0/src/hwpx/agent/document.py +0 -801
  101. python_hwpx-4.2.0/src/hwpx/agent/form_plan.py +0 -1760
  102. python_hwpx-4.2.0/src/hwpx/agent/model.py +0 -808
  103. python_hwpx-4.2.0/src/hwpx/agent/path.py +0 -155
  104. python_hwpx-4.2.0/src/hwpx/agent/query.py +0 -230
  105. python_hwpx-4.2.0/src/hwpx/agent/story.py +0 -207
  106. python_hwpx-4.2.0/src/hwpx/authoring.py +0 -3483
  107. python_hwpx-4.2.0/src/hwpx/benchmark/__init__.py +0 -25
  108. python_hwpx-4.2.0/src/hwpx/benchmark/blind_eval.py +0 -261
  109. python_hwpx-4.2.0/src/hwpx/builder/__init__.py +0 -52
  110. python_hwpx-4.2.0/src/hwpx/builder/core.py +0 -992
  111. python_hwpx-4.2.0/src/hwpx/builder/report.py +0 -195
  112. python_hwpx-4.2.0/src/hwpx/conformance/__init__.py +0 -54
  113. python_hwpx-4.2.0/src/hwpx/conformance/badges.py +0 -198
  114. python_hwpx-4.2.0/src/hwpx/conformance/corpus/corpus.json +0 -53
  115. python_hwpx-4.2.0/src/hwpx/conformance/corpus/meeting_summary.hwpx +0 -0
  116. python_hwpx-4.2.0/src/hwpx/conformance/corpus/notice.hwpx +0 -0
  117. python_hwpx-4.2.0/src/hwpx/conformance/corpus/report_table.hwpx +0 -0
  118. python_hwpx-4.2.0/src/hwpx/conformance/corpus.py +0 -260
  119. python_hwpx-4.2.0/src/hwpx/conformance/report.py +0 -223
  120. python_hwpx-4.2.0/src/hwpx/conformance/roundtrip_batch.py +0 -171
  121. python_hwpx-4.2.0/src/hwpx/conformance/runner.py +0 -395
  122. python_hwpx-4.2.0/src/hwpx/design/__init__.py +0 -30
  123. python_hwpx-4.2.0/src/hwpx/design/_support.py +0 -144
  124. python_hwpx-4.2.0/src/hwpx/design/composer.py +0 -282
  125. python_hwpx-4.2.0/src/hwpx/design/harvest.py +0 -305
  126. python_hwpx-4.2.0/src/hwpx/design/plan.py +0 -69
  127. python_hwpx-4.2.0/src/hwpx/design/profile.py +0 -88
  128. python_hwpx-4.2.0/src/hwpx/design/profiles/application_form/fragments/body.xml +0 -1
  129. python_hwpx-4.2.0/src/hwpx/design/profiles/application_form/fragments/heading.xml +0 -1
  130. python_hwpx-4.2.0/src/hwpx/design/profiles/application_form/fragments/info_table.xml +0 -1
  131. python_hwpx-4.2.0/src/hwpx/design/profiles/application_form/fragments/title.xml +0 -1
  132. python_hwpx-4.2.0/src/hwpx/design/profiles/application_form/profile.json +0 -25
  133. python_hwpx-4.2.0/src/hwpx/design/profiles/application_form/template.hwpx +0 -0
  134. python_hwpx-4.2.0/src/hwpx/design/profiles/home_notice/fragments/body.xml +0 -1
  135. python_hwpx-4.2.0/src/hwpx/design/profiles/home_notice/fragments/heading.xml +0 -1
  136. python_hwpx-4.2.0/src/hwpx/design/profiles/home_notice/fragments/title.xml +0 -1
  137. python_hwpx-4.2.0/src/hwpx/design/profiles/home_notice/profile.json +0 -24
  138. python_hwpx-4.2.0/src/hwpx/design/profiles/home_notice/template.hwpx +0 -0
  139. python_hwpx-4.2.0/src/hwpx/design/profiles/official_notice/fragments/body.xml +0 -1
  140. python_hwpx-4.2.0/src/hwpx/design/profiles/official_notice/fragments/heading.xml +0 -1
  141. python_hwpx-4.2.0/src/hwpx/design/profiles/official_notice/fragments/info_table.xml +0 -1
  142. python_hwpx-4.2.0/src/hwpx/design/profiles/official_notice/fragments/title.xml +0 -1
  143. python_hwpx-4.2.0/src/hwpx/design/profiles/official_notice/profile.json +0 -25
  144. python_hwpx-4.2.0/src/hwpx/design/profiles/official_notice/template.hwpx +0 -0
  145. python_hwpx-4.2.0/src/hwpx/design/profiles/report/fragments/body.xml +0 -1
  146. python_hwpx-4.2.0/src/hwpx/design/profiles/report/fragments/heading.xml +0 -1
  147. python_hwpx-4.2.0/src/hwpx/design/profiles/report/fragments/info_table.xml +0 -1
  148. python_hwpx-4.2.0/src/hwpx/design/profiles/report/fragments/title.xml +0 -1
  149. python_hwpx-4.2.0/src/hwpx/design/profiles/report/profile.json +0 -25
  150. python_hwpx-4.2.0/src/hwpx/design/profiles/report/template.hwpx +0 -0
  151. python_hwpx-4.2.0/src/hwpx/design/validator.py +0 -107
  152. python_hwpx-4.2.0/src/hwpx/evalplan_fill.py +0 -2727
  153. python_hwpx-4.2.0/src/hwpx/exam/__init__.py +0 -22
  154. python_hwpx-4.2.0/src/hwpx/exam/compose.py +0 -237
  155. python_hwpx-4.2.0/src/hwpx/exam/ir.py +0 -41
  156. python_hwpx-4.2.0/src/hwpx/exam/measure.py +0 -147
  157. python_hwpx-4.2.0/src/hwpx/exam/parser.py +0 -145
  158. python_hwpx-4.2.0/src/hwpx/exam/profile.py +0 -116
  159. python_hwpx-4.2.0/src/hwpx/fill_residue.py +0 -200
  160. python_hwpx-4.2.0/src/hwpx/form_fill.py +0 -333
  161. python_hwpx-4.2.0/src/hwpx/form_fit/seal.py +0 -450
  162. python_hwpx-4.2.0/src/hwpx/form_fit/wordbox.py +0 -1238
  163. python_hwpx-4.2.0/src/hwpx/formfill_quality.py +0 -822
  164. python_hwpx-4.2.0/src/hwpx/guidance_scan.py +0 -616
  165. python_hwpx-4.2.0/src/hwpx/presets/__init__.py +0 -22
  166. python_hwpx-4.2.0/src/hwpx/presets/proposal.py +0 -538
  167. python_hwpx-4.2.0/src/hwpx/template_formfit.py +0 -627
  168. python_hwpx-4.2.0/src/hwpx/tools/advanced_generators.py +0 -154
  169. python_hwpx-4.2.0/src/hwpx/tools/fuzz/__init__.py +0 -36
  170. python_hwpx-4.2.0/src/hwpx/tools/fuzz/__main__.py +0 -80
  171. python_hwpx-4.2.0/src/hwpx/tools/fuzz/catalog.py +0 -320
  172. python_hwpx-4.2.0/src/hwpx/tools/fuzz/generator.py +0 -195
  173. python_hwpx-4.2.0/src/hwpx/tools/fuzz/minimize.py +0 -33
  174. python_hwpx-4.2.0/src/hwpx/tools/fuzz/runner.py +0 -502
  175. python_hwpx-4.2.0/src/hwpx/tools/official_lint.py +0 -478
  176. python_hwpx-4.2.0/src/hwpx/tools/pii.py +0 -389
  177. python_hwpx-4.2.0/src/hwpx/tools/report_parser.py +0 -135
  178. python_hwpx-4.2.0/src/hwpx/tools/style_profile.py +0 -437
  179. python_hwpx-4.2.0/src/hwpx/tools/table_compute.py +0 -477
  180. python_hwpx-4.2.0/src/hwpx/visual/__init__.py +0 -115
  181. python_hwpx-4.2.0/src/hwpx/visual/_hancom_open_rate.ps1 +0 -374
  182. python_hwpx-4.2.0/src/hwpx/visual/_refresh_hwpx_mac.applescript +0 -162
  183. python_hwpx-4.2.0/src/hwpx/visual/_render_hwpx.ps1 +0 -72
  184. python_hwpx-4.2.0/src/hwpx/visual/_render_hwpx_mac.applescript +0 -249
  185. python_hwpx-4.2.0/src/hwpx/visual/detectors.py +0 -151
  186. python_hwpx-4.2.0/src/hwpx/visual/diff.py +0 -153
  187. python_hwpx-4.2.0/src/hwpx/visual/fixture_corpus.py +0 -210
  188. python_hwpx-4.2.0/src/hwpx/visual/hancom_worker.py +0 -287
  189. python_hwpx-4.2.0/src/hwpx/visual/masks.py +0 -51
  190. python_hwpx-4.2.0/src/hwpx/visual/oracle.py +0 -942
  191. python_hwpx-4.2.0/src/hwpx/visual/page_qa.py +0 -244
  192. python_hwpx-4.2.0/src/hwpx/visual/qa_contracts.py +0 -293
  193. python_hwpx-4.2.0/src/hwpx/visual/qa_metrics.py +0 -236
  194. python_hwpx-4.2.0/src/hwpx/visual/report.py +0 -47
  195. python_hwpx-4.2.0/src/python_hwpx.egg-info/SOURCES.txt +0 -376
  196. python_hwpx-4.2.0/tests/test_advanced_generators.py +0 -117
  197. python_hwpx-4.2.0/tests/test_agent_blueprint_contracts.py +0 -191
  198. python_hwpx-4.2.0/tests/test_agent_blueprint_dump.py +0 -321
  199. python_hwpx-4.2.0/tests/test_agent_blueprint_replay.py +0 -500
  200. python_hwpx-4.2.0/tests/test_agent_catalog.py +0 -38
  201. python_hwpx-4.2.0/tests/test_agent_cli.py +0 -525
  202. python_hwpx-4.2.0/tests/test_agent_commands.py +0 -1114
  203. python_hwpx-4.2.0/tests/test_agent_contracts.py +0 -239
  204. python_hwpx-4.2.0/tests/test_agent_document.py +0 -201
  205. python_hwpx-4.2.0/tests/test_agent_mixed_form.py +0 -726
  206. python_hwpx-4.2.0/tests/test_agent_path_query.py +0 -128
  207. python_hwpx-4.2.0/tests/test_agent_story_commands.py +0 -602
  208. python_hwpx-4.2.0/tests/test_authoring_native_toc.py +0 -240
  209. python_hwpx-4.2.0/tests/test_authoring_profile_routing.py +0 -148
  210. python_hwpx-4.2.0/tests/test_authoring_profile_routing_oracle.py +0 -84
  211. python_hwpx-4.2.0/tests/test_authoring_render_check.py +0 -56
  212. python_hwpx-4.2.0/tests/test_authoring_v2_block_validation.py +0 -180
  213. python_hwpx-4.2.0/tests/test_body_patch.py +0 -222
  214. python_hwpx-4.2.0/tests/test_builder_core.py +0 -945
  215. python_hwpx-4.2.0/tests/test_builder_plan_v2.py +0 -308
  216. python_hwpx-4.2.0/tests/test_builder_vertical_slice.py +0 -165
  217. python_hwpx-4.2.0/tests/test_conformance.py +0 -423
  218. python_hwpx-4.2.0/tests/test_corpus_toc_verify.py +0 -452
  219. python_hwpx-4.2.0/tests/test_design_builder.py +0 -316
  220. python_hwpx-4.2.0/tests/test_document_plan.py +0 -824
  221. python_hwpx-4.2.0/tests/test_document_plan_computed_fields.py +0 -137
  222. python_hwpx-4.2.0/tests/test_evalplan_fill.py +0 -1166
  223. python_hwpx-4.2.0/tests/test_exam_compose.py +0 -85
  224. python_hwpx-4.2.0/tests/test_exam_compose_oracle.py +0 -39
  225. python_hwpx-4.2.0/tests/test_exam_fixtures.py +0 -20
  226. python_hwpx-4.2.0/tests/test_exam_ir.py +0 -19
  227. python_hwpx-4.2.0/tests/test_exam_measure.py +0 -46
  228. python_hwpx-4.2.0/tests/test_exam_parser.py +0 -74
  229. python_hwpx-4.2.0/tests/test_exam_profile.py +0 -39
  230. python_hwpx-4.2.0/tests/test_fill_residue.py +0 -71
  231. python_hwpx-4.2.0/tests/test_form_fill_split_run.py +0 -301
  232. python_hwpx-4.2.0/tests/test_form_fit_seal.py +0 -125
  233. python_hwpx-4.2.0/tests/test_form_fit_seal_placement.py +0 -378
  234. python_hwpx-4.2.0/tests/test_form_fit_wordbox.py +0 -1144
  235. python_hwpx-4.2.0/tests/test_formfill_differential_driver.py +0 -482
  236. python_hwpx-4.2.0/tests/test_formfill_quality.py +0 -216
  237. python_hwpx-4.2.0/tests/test_government_report_preset.py +0 -121
  238. python_hwpx-4.2.0/tests/test_government_table_profile.py +0 -78
  239. python_hwpx-4.2.0/tests/test_guidance_scan.py +0 -195
  240. python_hwpx-4.2.0/tests/test_hancom_render_worker.py +0 -140
  241. python_hwpx-4.2.0/tests/test_id_integrity.py +0 -93
  242. python_hwpx-4.2.0/tests/test_kordoc_absorption.py +0 -288
  243. python_hwpx-4.2.0/tests/test_m9_p0_spike_tools.py +0 -109
  244. python_hwpx-4.2.0/tests/test_mail_merge_fit.py +0 -129
  245. python_hwpx-4.2.0/tests/test_mail_merge_table_compute.py +0 -143
  246. python_hwpx-4.2.0/tests/test_mixed_form_plan.py +0 -426
  247. python_hwpx-4.2.0/tests/test_mutation_contract_unification.py +0 -104
  248. python_hwpx-4.2.0/tests/test_mutation_report_projections.py +0 -318
  249. python_hwpx-4.2.0/tests/test_official_document_style.py +0 -134
  250. python_hwpx-4.2.0/tests/test_official_lint_gongmun_gate.py +0 -60
  251. python_hwpx-4.2.0/tests/test_official_lint_tableaware.py +0 -21
  252. python_hwpx-4.2.0/tests/test_openrate.py +0 -1075
  253. python_hwpx-4.2.0/tests/test_pii.py +0 -96
  254. python_hwpx-4.2.0/tests/test_pii_leak_sweep.py +0 -280
  255. python_hwpx-4.2.0/tests/test_pii_structural.py +0 -149
  256. python_hwpx-4.2.0/tests/test_pii_wiring.py +0 -103
  257. python_hwpx-4.2.0/tests/test_proposal_preset.py +0 -47
  258. python_hwpx-4.2.0/tests/test_question_split_detector.py +0 -27
  259. python_hwpx-4.2.0/tests/test_report_parser.py +0 -79
  260. python_hwpx-4.2.0/tests/test_rhwp_t1_gates.py +0 -276
  261. python_hwpx-4.2.0/tests/test_rhwp_t2_verification.py +0 -258
  262. python_hwpx-4.2.0/tests/test_save_pipeline_no_bypass.py +0 -152
  263. python_hwpx-4.2.0/tests/test_schema_freeze.py +0 -219
  264. python_hwpx-4.2.0/tests/test_stable_surface.py +0 -145
  265. python_hwpx-4.2.0/tests/test_style_profile.py +0 -114
  266. python_hwpx-4.2.0/tests/test_template_formfit.py +0 -404
  267. python_hwpx-4.2.0/tests/test_visual_fixture_corpus.py +0 -88
  268. python_hwpx-4.2.0/tests/test_visual_oracle.py +0 -312
  269. python_hwpx-4.2.0/tests/test_visual_oracle_budget.py +0 -207
  270. python_hwpx-4.2.0/tests/test_visual_qa_contracts.py +0 -102
  271. python_hwpx-4.2.0/tests/test_visual_qa_metrics.py +0 -89
  272. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/LICENSE +0 -0
  273. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/NOTICE +0 -0
  274. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/setup.cfg +0 -0
  275. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/data/Skeleton.hwpx +0 -0
  276. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/equation/__init__.py +0 -0
  277. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/equation/eqedit.py +0 -0
  278. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/equation/mathml.py +0 -0
  279. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/equation/render.py +0 -0
  280. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/equation/tokens.py +0 -0
  281. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/experimental.py +0 -0
  282. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/form_fit/__init__.py +0 -0
  283. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/form_fit/apply.py +0 -0
  284. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/form_fit/policy.py +0 -0
  285. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/form_fit/report.py +0 -0
  286. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/ingest/__init__.py +0 -0
  287. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/ingest/base.py +0 -0
  288. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/ingest/hwpx_converter.py +0 -0
  289. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/layout/__init__.py +0 -0
  290. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/layout/lint.py +0 -0
  291. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/layout/report.py +0 -0
  292. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/mutation_report.py +0 -0
  293. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/opc/relationships.py +0 -0
  294. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/opc/security.py +0 -0
  295. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/opc/xml_utils.py +0 -0
  296. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/__init__.py +0 -0
  297. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/_document_impl.py +0 -0
  298. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/_document_primitives.py +0 -0
  299. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/canonical_defaults.py +0 -0
  300. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/common.py +0 -0
  301. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/document.py +0 -0
  302. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/document_parts.py +0 -0
  303. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/header.py +0 -0
  304. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/header_part.py +0 -0
  305. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/memo.py +0 -0
  306. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/namespaces.py +0 -0
  307. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/numbering.py +0 -0
  308. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/parser.py +0 -0
  309. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/run.py +0 -0
  310. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/schema.py +0 -0
  311. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/section.py +0 -0
  312. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/section_format.py +0 -0
  313. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/section_story.py +0 -0
  314. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/simple_parts.py +0 -0
  315. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/table.py +0 -0
  316. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/oxml/utils.py +0 -0
  317. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/package.py +0 -0
  318. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/py.typed +0 -0
  319. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/quality/__init__.py +0 -0
  320. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/quality/ledger.py +0 -0
  321. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/quality/policy.py +0 -0
  322. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/templates.py +0 -0
  323. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/_schemas/header.xsd +0 -0
  324. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/_schemas/section.xsd +0 -0
  325. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/archive_cli.py +0 -0
  326. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/document_viewer.py +0 -0
  327. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/generic_inventory.py +0 -0
  328. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/id_integrity.py +0 -0
  329. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/idempotence.py +0 -0
  330. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/ir_equality.py +0 -0
  331. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/layout_preview.py +0 -0
  332. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/markdown_export.py +0 -0
  333. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/object_finder.py +0 -0
  334. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/package_reconcile.py +0 -0
  335. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/package_validator.py +0 -0
  336. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/recover.py +0 -0
  337. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/repair.py +0 -0
  338. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/report_utils.py +0 -0
  339. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/roundtrip_diff.py +0 -0
  340. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/table_cleanup.py +0 -0
  341. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/table_navigation.py +0 -0
  342. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/text_extract_cli.py +0 -0
  343. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/text_extractor.py +0 -0
  344. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/hwpx/tools/validator.py +0 -0
  345. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/python_hwpx.egg-info/dependency_links.txt +0 -0
  346. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/src/python_hwpx.egg-info/top_level.txt +0 -0
  347. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_byte_patch_identity.py +0 -0
  348. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_cell_line_spacing.py +0 -0
  349. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_comment_node_robustness.py +0 -0
  350. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_coverage_promotion.py +0 -0
  351. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_coverage_targets.py +0 -0
  352. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_deviations_registry.py +0 -0
  353. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_document_context_manager.py +0 -0
  354. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_document_save_api.py +0 -0
  355. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_document_viewer.py +0 -0
  356. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_equation_converter.py +0 -0
  357. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_equation_render.py +0 -0
  358. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_existing_document_format_editing.py +0 -0
  359. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_form_fields.py +0 -0
  360. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_gap_closure_tools.py +0 -0
  361. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_hp_tab_support.py +0 -0
  362. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_hwpxlib_corpus_read.py +0 -0
  363. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_id_generator_range.py +0 -0
  364. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_image_object_workflow.py +0 -0
  365. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_ingest.py +0 -0
  366. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_inline_models.py +0 -0
  367. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_integration_hwpx_compatibility.py +0 -0
  368. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_integration_roundtrip.py +0 -0
  369. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_layout_lint.py +0 -0
  370. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_layout_preview.py +0 -0
  371. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_markdown_export.py +0 -0
  372. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_memo_and_style_editing.py +0 -0
  373. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_namespace_handling.py +0 -0
  374. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_opc_package.py +0 -0
  375. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_open_safety_corpus.py +0 -0
  376. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_oxml_parsing.py +0 -0
  377. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_packaging_license_metadata.py +0 -0
  378. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_packaging_py_typed.py +0 -0
  379. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_paragraph_keep_together.py +0 -0
  380. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_paragraph_section_management.py +0 -0
  381. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_public_runtime_boundary.py +0 -0
  382. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_recover_broken_zip.py +0 -0
  383. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_repair_repack.py +0 -0
  384. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_report_utils.py +0 -0
  385. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_repr_snapshots.py +0 -0
  386. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_roundtrip_fidelity.py +0 -0
  387. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_row_heights.py +0 -0
  388. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_skeleton_template_ids.py +0 -0
  389. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_split_cell.py +0 -0
  390. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_split_merged_cell.py +0 -0
  391. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_table_cleanup.py +0 -0
  392. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_table_navigation.py +0 -0
  393. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_table_patch_dryrun.py +0 -0
  394. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_tables_default_border.py +0 -0
  395. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_text_extractor_annotations.py +0 -0
  396. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_validation_severity.py +0 -0
  397. {python_hwpx-4.2.0 → python_hwpx-5.0.1}/tests/test_validator_comment_nodes.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-hwpx
3
- Version: 4.2.0
4
- Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
3
+ Version: 5.0.1
4
+ Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 문서 라이브러리
5
5
  Author: python-hwpx Maintainers
6
6
  License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/airmang/python-hwpx
@@ -22,9 +22,6 @@ License-File: LICENSE
22
22
  License-File: NOTICE
23
23
  Requires-Dist: lxml<7,>=4.9
24
24
  Provides-Extra: visual
25
- Requires-Dist: pymupdf>=1.24; extra == "visual"
26
- Requires-Dist: pillow>=10.0; extra == "visual"
27
- Requires-Dist: numpy>=1.26; extra == "visual"
28
25
  Provides-Extra: xlsx
29
26
  Requires-Dist: openpyxl>=3.1; extra == "xlsx"
30
27
  Provides-Extra: preview
@@ -37,9 +34,11 @@ Requires-Dist: latex2mathml>=3.77; extra == "dev"
37
34
  Provides-Extra: test
38
35
  Requires-Dist: build>=1.0; extra == "test"
39
36
  Requires-Dist: numpy>=1.26; extra == "test"
37
+ Requires-Dist: openpyxl>=3.1; extra == "test"
40
38
  Requires-Dist: pillow>=10.0; extra == "test"
41
39
  Requires-Dist: pytest>=7.4; extra == "test"
42
40
  Requires-Dist: pytest-cov>=5.0; extra == "test"
41
+ Requires-Dist: pyyaml<7,>=6.0; extra == "test"
43
42
  Requires-Dist: ruff>=0.12; extra == "test"
44
43
  Requires-Dist: latex2mathml>=3.77; extra == "test"
45
44
  Provides-Extra: typecheck
@@ -66,13 +65,24 @@ Dynamic: license-file
66
65
 
67
66
  기존 문서는 손댄 곳만 고치고(미수정 영역은 바이트 그대로), 새 문서는 실제
68
67
  한컴오피스가 받아들이는 형태로 만듭니다. HWPX는 ZIP+XML(OWPML/OPC) 구조라
69
- Windows·macOS·Linux·CI 어디서든 순수 파이썬으로 동작합니다.
68
+ Windows·macOS·Linux·CI 어디서든 순수 파이썬으로 동작합니다. 한컴오피스도
69
+ Windows도 필요하지 않으므로 **ChatGPT 채팅 환경에서도 HWPX 문서를 만들고
70
+ 고칠 수 있습니다** — 파이썬이 도는 곳이면 됩니다.
70
71
 
71
- | | 레포 | 역할 |
72
+ | 계층 | 저장소 | 정본 책임 |
72
73
  |---|---|---|
73
- | 📦 | **`python-hwpx`** | 순수 파이썬 HWPX 코어 (이 레포) |
74
- | 🔌 | [`hwpx-mcp-server`](https://github.com/airmang/hwpx-mcp-server) | MCP 클라이언트(Claude Desktop 등)에서 HWPX 조작 |
75
- | 🎯 | [`hwpx-plugin`](https://github.com/airmang/hwpx-plugins) | 에이전트용 플러그인·스킬 번들 |
74
+ | Core | [`python-hwpx`](https://github.com/airmang/python-hwpx) | HWPX package/object model·OPC/OXML·직렬화·재사용 primitive |
75
+ | Automation | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation) | Python 자동화·워크플로·profile/policy·렌더·선택형 MCP adapter |
76
+ | Judgment | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) | 에이전트 intent/genre 판단·ambiguity 처리·plugin/skill 가이드 |
77
+
78
+ 이 저장소는 위 표의 Core 정본입니다. 5.0의 모듈 소유권, 삭제 경로 재등장
79
+ 방지, 의존성 허용 범위는
80
+ [제품 경계 문서](docs/architecture/product-boundary.md)에 고정돼 있습니다.
81
+
82
+ > **Python 블록 판정:** 이 current manual의 모든 Python 블록은
83
+ > [실행 분류 ledger](docs/python-example-ledger.json)에 exact source digest와 함께
84
+ > 동결돼 있습니다. **독립 실행 예제** 표시가 없는 블록은 기존 입력 파일이나 앞
85
+ > 문맥을 요구하는 조각이며, 그대로 실행할 수 있는 예제로 간주하지 않습니다.
76
86
 
77
87
  ## 시작하기
78
88
 
@@ -80,6 +90,11 @@ Windows·macOS·Linux·CI 어디서든 순수 파이썬으로 동작합니다.
80
90
  pip install python-hwpx # Python 3.10+
81
91
  ```
82
92
 
93
+ > **5.x 호환 extra:** `pip install "python-hwpx[visual]"`은 기존 설치 명령을
94
+ > 깨뜨리지 않기 위해 계속 허용되지만, `visual` extra는 비어 있어 PDF·이미지
95
+ > 렌더링 의존성을 설치하지 않습니다. 렌더·PDF 이미징 실행은
96
+ > `python-hwpx-automation[oracle]`이 소유합니다.
97
+
83
98
  ```python
84
99
  from hwpx import HwpxDocument
85
100
 
@@ -88,14 +103,21 @@ doc.add_paragraph("자동화로 추가한 문단입니다.")
88
103
  doc.save_to_path("보고서-수정.hwpx")
89
104
  ```
90
105
 
106
+ 백지에서 새 문서를 만들 때는 `HwpxDocument.new()`로 시작해 같은 API로
107
+ 문단·표·머리말을 채우고 `save_to_path()`로 저장합니다.
108
+
109
+ 문서 저작·양식 채움·시험지 조판 같은 상위 워크플로가 필요하면
110
+ [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation)을
111
+ 함께 설치하세요. MCP SDK 없이 같은 환경에서 그대로 동작합니다.
112
+
91
113
  ## 무엇을 하나
92
114
 
93
115
  - **읽기·추출** — 텍스트/HTML/rich Markdown 내보내기(서식·중첩 표·각주 보존), XPath 객체 탐색
94
116
  - **편집** — 문단·표·이미지·머리글/바닥글·메모·각주, 줄간격·여백·쪽번호 등 서식
95
117
  - **양식 채우기** — 라벨·경로 기반 셀 채움, 바이트 보존 구조 편집(행·열·오토핏·shrink-to-fit)
96
- - **생성**조립형 builder, 공문 lint·결재란, 사진대지·명패·조직도, mail merge, 신구대조표
118
+ - **생성·일괄 처리** 문단·표·이미지·목차·상호참조 저작, 명시적 sanitizer 기반 mail merge, 텍스트 diff
97
119
  - **변경추적·목차** — redline 저작, 네이티브 목차·상호참조
98
- - **검증·안전** — XSD·패키지 검증 CLI, 열림 안전 게이트, 모든 쓰기에 영수증(`MutationReport`)
120
+ - **검증·안전** — 패키지 구조 검증 CLI, 열림 안전 게이트, 모든 쓰기에 영수증(`MutationReport`) — 번들 XSD는 느슨한 구조 스키마이며 OWPML 전체 검증은 아닙니다
99
121
 
100
122
  자세한 내용: [사용 가이드](docs/usage.md) · [API 레퍼런스](https://airmang.github.io/python-hwpx/) · [안정 API 표면](docs/stable-api.md) · [예제](docs/examples.md)
101
123
 
@@ -139,6 +161,23 @@ print(report.preservation.untouched_part_payloads.to_dict())
139
161
  > 위 수치는 *생성물 수용률* 축입니다(만든 파일을 실한컴이 받는가). 문서 *파싱 recall*과는
140
162
  > 다른 축이므로 파서 프로젝트 수치와 병치 비교하지 마세요.
141
163
 
164
+ ## 어디서 쓰나
165
+
166
+ | 환경 | 무엇을 하면 되나 |
167
+ |---|---|
168
+ | 일반 ChatGPT 대화 | `.hwpx`를 올리고 `pip install python-hwpx` 후 파이썬으로 편집해 되받기 |
169
+ | 로컬·서버 파이썬 | `pip install python-hwpx` — 스크립트·배치·CI |
170
+ | 파이썬 자동화 (MCP 없이) | `pip install python-hwpx-automation` — 저작·양식 채움·검증 워크플로를 그냥 파이썬으로 |
171
+ | ChatGPT MCP 앱 | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation)의 MCP adapter를 커넥터로 등록 |
172
+ | Codex 마켓플레이스 플러그인 | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) 설치 |
173
+ | Claude Code · Hermes · OpenClaw | 같은 MCP 서버를 각 클라이언트에 등록 ([`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation)) |
174
+
175
+ 실측: 일반 ChatGPT 대화에 `.hwpx`를 올리고 python-hwpx 설치를 요청했을 때 PyPI
176
+ 설치가 성공했고, 문서를 편집해 되받았습니다. 다만 파이썬 실행과 네트워크 허용
177
+ 범위는 플랜·설정에 따라 다르므로 모든 계정에서 보장되는 경로는 아닙니다.
178
+ 네트워크가 막힌 실행 환경에서는 wheel 파일을 함께 업로드하면 오프라인 설치로
179
+ 같은 여정이 됩니다.
180
+
142
181
  ## 비교
143
182
 
144
183
  | | python-hwpx | pyhwpx | pyhwp |
@@ -147,14 +186,17 @@ print(report.preservation.untouched_part_payloads.to_dict())
147
186
  | **한/글 설치** | 불필요 | 필요 (Windows COM) | 불필요 |
148
187
  | **크로스 플랫폼** | ✅ Linux / macOS / Windows / CI | ❌ Windows 전용 | ✅ |
149
188
  | **편집/생성 API** | ✅ | ✅ (COM) | ❌ 대부분 읽기 |
150
- | **AI 에이전트 연동 (MCP)** | ✅ | ❌ | ❌ |
189
+ | **AI 에이전트 연동 (MCP)** | ✅ companion 경유 | ❌ | ❌ |
151
190
 
152
191
  > HWP(v5 바이너리)는 지원하지 않습니다. 한컴오피스에서 HWPX로 변환 후 사용하세요.
153
192
 
154
193
  ## 알려진 제약
155
194
 
156
- - `add_shape()` / `add_control()`은 한/글이 요구하는 모든 하위 요소를 생성하지 않습니다.
157
- - `<hp:pic>` 그림 개체의 완전 자동 생성은 제공하지 않습니다.
195
+ - `add_shape()` / `add_control()`은 한/글이 요구하는 모든 하위 요소를 생성하지 않는
196
+ 저수준 탈출구입니다. 그대로 저장한 문서는 한/글이 열지 못하며, 신호는 호출 시점의
197
+ 경고 하나뿐입니다(저장도 패키지 검증도 막지 않습니다). 도형은 `add_line()` /
198
+ `add_rectangle()` / `add_ellipse()`를 쓰세요.
199
+ - 그림은 단순 개체 생성까지 지원하며, 그룹·효과 같은 복잡 개체 생성은 미지원입니다.
158
200
  - 암호화된 HWPX는 지원하지 않습니다.
159
201
 
160
202
  ## 기여하기
@@ -17,13 +17,24 @@
17
17
 
18
18
  기존 문서는 손댄 곳만 고치고(미수정 영역은 바이트 그대로), 새 문서는 실제
19
19
  한컴오피스가 받아들이는 형태로 만듭니다. HWPX는 ZIP+XML(OWPML/OPC) 구조라
20
- Windows·macOS·Linux·CI 어디서든 순수 파이썬으로 동작합니다.
20
+ Windows·macOS·Linux·CI 어디서든 순수 파이썬으로 동작합니다. 한컴오피스도
21
+ Windows도 필요하지 않으므로 **ChatGPT 채팅 환경에서도 HWPX 문서를 만들고
22
+ 고칠 수 있습니다** — 파이썬이 도는 곳이면 됩니다.
21
23
 
22
- | | 레포 | 역할 |
24
+ | 계층 | 저장소 | 정본 책임 |
23
25
  |---|---|---|
24
- | 📦 | **`python-hwpx`** | 순수 파이썬 HWPX 코어 (이 레포) |
25
- | 🔌 | [`hwpx-mcp-server`](https://github.com/airmang/hwpx-mcp-server) | MCP 클라이언트(Claude Desktop 등)에서 HWPX 조작 |
26
- | 🎯 | [`hwpx-plugin`](https://github.com/airmang/hwpx-plugins) | 에이전트용 플러그인·스킬 번들 |
26
+ | Core | [`python-hwpx`](https://github.com/airmang/python-hwpx) | HWPX package/object model·OPC/OXML·직렬화·재사용 primitive |
27
+ | Automation | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation) | Python 자동화·워크플로·profile/policy·렌더·선택형 MCP adapter |
28
+ | Judgment | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) | 에이전트 intent/genre 판단·ambiguity 처리·plugin/skill 가이드 |
29
+
30
+ 이 저장소는 위 표의 Core 정본입니다. 5.0의 모듈 소유권, 삭제 경로 재등장
31
+ 방지, 의존성 허용 범위는
32
+ [제품 경계 문서](docs/architecture/product-boundary.md)에 고정돼 있습니다.
33
+
34
+ > **Python 블록 판정:** 이 current manual의 모든 Python 블록은
35
+ > [실행 분류 ledger](docs/python-example-ledger.json)에 exact source digest와 함께
36
+ > 동결돼 있습니다. **독립 실행 예제** 표시가 없는 블록은 기존 입력 파일이나 앞
37
+ > 문맥을 요구하는 조각이며, 그대로 실행할 수 있는 예제로 간주하지 않습니다.
27
38
 
28
39
  ## 시작하기
29
40
 
@@ -31,6 +42,11 @@ Windows·macOS·Linux·CI 어디서든 순수 파이썬으로 동작합니다.
31
42
  pip install python-hwpx # Python 3.10+
32
43
  ```
33
44
 
45
+ > **5.x 호환 extra:** `pip install "python-hwpx[visual]"`은 기존 설치 명령을
46
+ > 깨뜨리지 않기 위해 계속 허용되지만, `visual` extra는 비어 있어 PDF·이미지
47
+ > 렌더링 의존성을 설치하지 않습니다. 렌더·PDF 이미징 실행은
48
+ > `python-hwpx-automation[oracle]`이 소유합니다.
49
+
34
50
  ```python
35
51
  from hwpx import HwpxDocument
36
52
 
@@ -39,14 +55,21 @@ doc.add_paragraph("자동화로 추가한 문단입니다.")
39
55
  doc.save_to_path("보고서-수정.hwpx")
40
56
  ```
41
57
 
58
+ 백지에서 새 문서를 만들 때는 `HwpxDocument.new()`로 시작해 같은 API로
59
+ 문단·표·머리말을 채우고 `save_to_path()`로 저장합니다.
60
+
61
+ 문서 저작·양식 채움·시험지 조판 같은 상위 워크플로가 필요하면
62
+ [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation)을
63
+ 함께 설치하세요. MCP SDK 없이 같은 환경에서 그대로 동작합니다.
64
+
42
65
  ## 무엇을 하나
43
66
 
44
67
  - **읽기·추출** — 텍스트/HTML/rich Markdown 내보내기(서식·중첩 표·각주 보존), XPath 객체 탐색
45
68
  - **편집** — 문단·표·이미지·머리글/바닥글·메모·각주, 줄간격·여백·쪽번호 등 서식
46
69
  - **양식 채우기** — 라벨·경로 기반 셀 채움, 바이트 보존 구조 편집(행·열·오토핏·shrink-to-fit)
47
- - **생성**조립형 builder, 공문 lint·결재란, 사진대지·명패·조직도, mail merge, 신구대조표
70
+ - **생성·일괄 처리** 문단·표·이미지·목차·상호참조 저작, 명시적 sanitizer 기반 mail merge, 텍스트 diff
48
71
  - **변경추적·목차** — redline 저작, 네이티브 목차·상호참조
49
- - **검증·안전** — XSD·패키지 검증 CLI, 열림 안전 게이트, 모든 쓰기에 영수증(`MutationReport`)
72
+ - **검증·안전** — 패키지 구조 검증 CLI, 열림 안전 게이트, 모든 쓰기에 영수증(`MutationReport`) — 번들 XSD는 느슨한 구조 스키마이며 OWPML 전체 검증은 아닙니다
50
73
 
51
74
  자세한 내용: [사용 가이드](docs/usage.md) · [API 레퍼런스](https://airmang.github.io/python-hwpx/) · [안정 API 표면](docs/stable-api.md) · [예제](docs/examples.md)
52
75
 
@@ -90,6 +113,23 @@ print(report.preservation.untouched_part_payloads.to_dict())
90
113
  > 위 수치는 *생성물 수용률* 축입니다(만든 파일을 실한컴이 받는가). 문서 *파싱 recall*과는
91
114
  > 다른 축이므로 파서 프로젝트 수치와 병치 비교하지 마세요.
92
115
 
116
+ ## 어디서 쓰나
117
+
118
+ | 환경 | 무엇을 하면 되나 |
119
+ |---|---|
120
+ | 일반 ChatGPT 대화 | `.hwpx`를 올리고 `pip install python-hwpx` 후 파이썬으로 편집해 되받기 |
121
+ | 로컬·서버 파이썬 | `pip install python-hwpx` — 스크립트·배치·CI |
122
+ | 파이썬 자동화 (MCP 없이) | `pip install python-hwpx-automation` — 저작·양식 채움·검증 워크플로를 그냥 파이썬으로 |
123
+ | ChatGPT MCP 앱 | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation)의 MCP adapter를 커넥터로 등록 |
124
+ | Codex 마켓플레이스 플러그인 | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) 설치 |
125
+ | Claude Code · Hermes · OpenClaw | 같은 MCP 서버를 각 클라이언트에 등록 ([`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation)) |
126
+
127
+ 실측: 일반 ChatGPT 대화에 `.hwpx`를 올리고 python-hwpx 설치를 요청했을 때 PyPI
128
+ 설치가 성공했고, 문서를 편집해 되받았습니다. 다만 파이썬 실행과 네트워크 허용
129
+ 범위는 플랜·설정에 따라 다르므로 모든 계정에서 보장되는 경로는 아닙니다.
130
+ 네트워크가 막힌 실행 환경에서는 wheel 파일을 함께 업로드하면 오프라인 설치로
131
+ 같은 여정이 됩니다.
132
+
93
133
  ## 비교
94
134
 
95
135
  | | python-hwpx | pyhwpx | pyhwp |
@@ -98,14 +138,17 @@ print(report.preservation.untouched_part_payloads.to_dict())
98
138
  | **한/글 설치** | 불필요 | 필요 (Windows COM) | 불필요 |
99
139
  | **크로스 플랫폼** | ✅ Linux / macOS / Windows / CI | ❌ Windows 전용 | ✅ |
100
140
  | **편집/생성 API** | ✅ | ✅ (COM) | ❌ 대부분 읽기 |
101
- | **AI 에이전트 연동 (MCP)** | ✅ | ❌ | ❌ |
141
+ | **AI 에이전트 연동 (MCP)** | ✅ companion 경유 | ❌ | ❌ |
102
142
 
103
143
  > HWP(v5 바이너리)는 지원하지 않습니다. 한컴오피스에서 HWPX로 변환 후 사용하세요.
104
144
 
105
145
  ## 알려진 제약
106
146
 
107
- - `add_shape()` / `add_control()`은 한/글이 요구하는 모든 하위 요소를 생성하지 않습니다.
108
- - `<hp:pic>` 그림 개체의 완전 자동 생성은 제공하지 않습니다.
147
+ - `add_shape()` / `add_control()`은 한/글이 요구하는 모든 하위 요소를 생성하지 않는
148
+ 저수준 탈출구입니다. 그대로 저장한 문서는 한/글이 열지 못하며, 신호는 호출 시점의
149
+ 경고 하나뿐입니다(저장도 패키지 검증도 막지 않습니다). 도형은 `add_line()` /
150
+ `add_rectangle()` / `add_ellipse()`를 쓰세요.
151
+ - 그림은 단순 개체 생성까지 지원하며, 그룹·효과 같은 복잡 개체 생성은 미지원입니다.
109
152
  - 암호화된 HWPX는 지원하지 않습니다.
110
153
 
111
154
  ## 기여하기
@@ -1,11 +1,11 @@
1
1
  [build-system]
2
- requires = ["setuptools>=77.0.0", "wheel"]
2
+ requires = ["setuptools==83.0.0", "wheel==0.47.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-hwpx"
7
- version = "4.2.0"
8
- description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리"
7
+ version = "5.0.1"
8
+ description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 문서 라이브러리"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  license = "Apache-2.0"
11
11
  license-files = ["LICENSE", "NOTICE"]
@@ -29,11 +29,10 @@ dependencies = [
29
29
  ]
30
30
 
31
31
  [project.optional-dependencies]
32
- visual = [
33
- "pymupdf>=1.24",
34
- "pillow>=10.0",
35
- "numpy>=1.26",
36
- ]
32
+ # 5.0에서 core는 PDF도 이미지도 읽지 않는다. 렌더 백엔드와 word-box 추출은
33
+ # 주입받는 계약이고, 그 스택은 companion 계층이 소유한다. 이름은 기존 설치가
34
+ # `python-hwpx[visual]`로 깨지지 않도록 남기되 아무것도 끌어오지 않는다.
35
+ visual = []
37
36
  # Excel(.xlsx/.xlsm) 명부 ingestion for mail_merge. Lazy-imported; absent => clear error.
38
37
  xlsx = [
39
38
  "openpyxl>=3.1",
@@ -52,9 +51,11 @@ dev = [
52
51
  test = [
53
52
  "build>=1.0",
54
53
  "numpy>=1.26",
54
+ "openpyxl>=3.1",
55
55
  "pillow>=10.0",
56
56
  "pytest>=7.4",
57
57
  "pytest-cov>=5.0",
58
+ "pyyaml>=6.0,<7",
58
59
  "ruff>=0.12",
59
60
  "latex2mathml>=3.77",
60
61
  ]
@@ -69,7 +70,11 @@ Documentation = "https://airmang.github.io/python-hwpx/"
69
70
  Issues = "https://github.com/airmang/python-hwpx/issues"
70
71
 
71
72
  [project.scripts]
72
- hwpx = "hwpx.agent.cli:main"
73
+ # The `hwpx` application CLI moved to python-hwpx-automation, which declares the
74
+ # name in the train that raises its core floor to 5.0 — so no valid install ever
75
+ # has two declarers of it. `hwpx-conformance` is gone too: its package is
76
+ # repository QA and no longer ships, and a console script pointing into an
77
+ # excluded package would install as a command that cannot start.
73
78
  hwpx-unpack = "hwpx.tools.archive_cli:unpack_main"
74
79
  hwpx-pack = "hwpx.tools.archive_cli:pack_main"
75
80
  hwpx-validate = "hwpx.tools.validator:main"
@@ -78,33 +83,52 @@ hwpx-page-guard = "hwpx.tools.page_guard:main"
78
83
  hwpx-analyze-template = "hwpx.tools.template_analyzer:main"
79
84
  hwpx-text-extract = "hwpx.tools.text_extract_cli:main"
80
85
  hwpx-repair = "hwpx.tools.repair:main"
81
- hwpx-conformance = "hwpx.conformance.runner:main"
82
86
 
83
87
  [tool.setuptools]
84
88
  package-dir = { "" = "src" }
85
89
  include-package-data = true
90
+ # Namespace-aware discovery. hwpx/opc and hwpx/data carry no __init__.py, so a
91
+ # plain find_packages misses them, and they only ever shipped because
92
+ # include-package-data swept them in as data files of hwpx. That same sweep kept
93
+ # hwpx/benchmark and hwpx/conformance in the wheel after they were excluded from
94
+ # the package list — one mechanism, helping in one place and hurting in the other.
95
+ # The list is deliberately exact. A wildcard made any new directory below
96
+ # ``src/hwpx`` publishable without a packaging review, which is the opposite of
97
+ # the library/application boundary. Namespace packages (``opc`` and ``data``)
98
+ # are valid explicit entries.
99
+ packages = [
100
+ "hwpx",
101
+ "hwpx._document",
102
+ "hwpx.data",
103
+ "hwpx.equation",
104
+ "hwpx.form_fit",
105
+ "hwpx.ingest",
106
+ "hwpx.layout",
107
+ "hwpx.opc",
108
+ "hwpx.oxml",
109
+ "hwpx.quality",
110
+ "hwpx.tools",
111
+ "hwpx.tools._schemas",
112
+ ]
86
113
 
87
- [tool.setuptools.packages.find]
88
- where = ["src"]
89
- include = ["hwpx*"]
114
+ # Only packages that ship. A key here for an excluded or deleted package pulls it
115
+ # back into the wheel: hwpx.conformance was excluded from packages.find and still
116
+ # shipped because this table named it, and hwpx.design no longer exists at all.
90
117
 
118
+ # Listed explicitly rather than discovered with an exclude pattern. The exclude
119
+ # form silently failed to keep hwpx.benchmark and hwpx.conformance out of the
120
+ # wheel, and a packaging rule that looks right while shipping the opposite is
121
+ # worse than a longer list. Adding a package here is a deliberate act.
91
122
  [tool.setuptools.package-data]
92
123
  "hwpx" = ["py.typed"]
93
124
  "hwpx.tools" = ["_schemas/*.xsd"]
94
125
  "hwpx.data" = ["Skeleton.hwpx"]
95
- "hwpx.visual" = ["_render_hwpx.ps1", "_render_hwpx_mac.applescript", "_refresh_hwpx_mac.applescript", "_hancom_open_rate.ps1"]
96
- "hwpx.design" = [
97
- "profiles/*/profile.json",
98
- "profiles/*/template.hwpx",
99
- "profiles/*/fragments/*.xml",
100
- ]
101
- "hwpx.conformance" = [
102
- "corpus/corpus.json",
103
- "corpus/*.hwpx",
104
- ]
105
126
 
106
127
  [tool.pytest.ini_options]
107
- pythonpath = ["src"]
128
+ # scripts/ carries repository QA harnesses that are not library surface — the
129
+ # fuzz loop moved there in 5.0 because it needs the MCP owner's builder, and
130
+ # core must never import a companion layer.
131
+ pythonpath = ["src", "scripts"]
108
132
  addopts = "-ra"
109
133
  testpaths = ["tests"]
110
134
 
@@ -124,6 +148,8 @@ files = [
124
148
  "src/hwpx/equation/mathml.py",
125
149
  "src/hwpx/equation/render.py",
126
150
  "src/hwpx/tools/document_viewer.py",
151
+ "src/hwpx/tools/mail_merge.py",
152
+ "src/hwpx/tools/redline.py",
127
153
  "src/hwpx/_document/_units.py",
128
154
  "src/hwpx/_document/fields.py",
129
155
  "src/hwpx/_document/layout.py",
@@ -132,9 +158,6 @@ files = [
132
158
  "src/hwpx/_document/persistence.py",
133
159
  "src/hwpx/_document/shapes.py",
134
160
  "src/hwpx/_document/tracked.py",
135
- "src/hwpx/agent/commands.py",
136
- "src/hwpx/agent/document.py",
137
- "src/hwpx/agent/story.py",
138
161
  "src/hwpx/oxml/_document_impl.py",
139
162
  "src/hwpx/oxml/_document_primitives.py",
140
163
  "src/hwpx/oxml/document.py",
@@ -153,6 +176,7 @@ files = [
153
176
  "src/hwpx/oxml/simple_parts.py",
154
177
  "src/hwpx/oxml/table.py",
155
178
  "src/hwpx/quality/policy.py",
179
+ "src/hwpx/quality/rendering.py",
156
180
  "src/hwpx/quality/report.py",
157
181
  "src/hwpx/tools/archive_cli.py",
158
182
  "src/hwpx/tools/package_validator.py",
@@ -160,7 +184,6 @@ files = [
160
184
  "src/hwpx/tools/template_analyzer.py",
161
185
  "src/hwpx/tools/text_extract_cli.py",
162
186
  "src/hwpx/tools/text_extractor.py",
163
- "src/hwpx/visual/oracle.py",
164
187
  "tests/template_automation/helpers.py",
165
188
  "tests/template_automation/generate_fixtures.py",
166
189
  ]
@@ -179,6 +202,8 @@ include = [
179
202
  "src/hwpx/equation/mathml.py",
180
203
  "src/hwpx/equation/render.py",
181
204
  "src/hwpx/tools/document_viewer.py",
205
+ "src/hwpx/tools/mail_merge.py",
206
+ "src/hwpx/tools/redline.py",
182
207
  "src/hwpx/_document/_units.py",
183
208
  "src/hwpx/_document/fields.py",
184
209
  "src/hwpx/_document/layout.py",
@@ -187,9 +212,6 @@ include = [
187
212
  "src/hwpx/_document/persistence.py",
188
213
  "src/hwpx/_document/shapes.py",
189
214
  "src/hwpx/_document/tracked.py",
190
- "src/hwpx/agent/commands.py",
191
- "src/hwpx/agent/document.py",
192
- "src/hwpx/agent/story.py",
193
215
  "src/hwpx/oxml/_document_impl.py",
194
216
  "src/hwpx/oxml/_document_primitives.py",
195
217
  "src/hwpx/oxml/document.py",
@@ -208,6 +230,7 @@ include = [
208
230
  "src/hwpx/oxml/simple_parts.py",
209
231
  "src/hwpx/oxml/table.py",
210
232
  "src/hwpx/quality/policy.py",
233
+ "src/hwpx/quality/rendering.py",
211
234
  "src/hwpx/quality/report.py",
212
235
  "src/hwpx/tools/archive_cli.py",
213
236
  "src/hwpx/tools/package_validator.py",
@@ -215,7 +238,6 @@ include = [
215
238
  "src/hwpx/tools/template_analyzer.py",
216
239
  "src/hwpx/tools/text_extract_cli.py",
217
240
  "src/hwpx/tools/text_extractor.py",
218
- "src/hwpx/visual/oracle.py",
219
241
  "tests/template_automation/helpers.py",
220
242
  "tests/template_automation/generate_fixtures.py",
221
243
  ]