python-hwpx-automation 6.0.4__tar.gz → 6.1.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 (223) hide show
  1. {python_hwpx_automation-6.0.4/src/python_hwpx_automation.egg-info → python_hwpx_automation-6.1.3}/PKG-INFO +55 -91
  2. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/README.md +48 -89
  3. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/pyproject.toml +7 -2
  4. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/form_fill.py +34 -0
  5. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/hwpx_ops.py +25 -0
  6. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/identity.json +10 -10
  7. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/form_fields.py +61 -0
  8. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/server.py +1 -0
  9. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/tool_bindings.py +1 -0
  10. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/tool_contract.py +12 -11
  11. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3/src/python_hwpx_automation.egg-info}/PKG-INFO +55 -91
  12. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/python_hwpx_automation.egg-info/requires.txt +1 -1
  13. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/LICENSE +0 -0
  14. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/MANIFEST.in +0 -0
  15. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/NOTICE +0 -0
  16. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/setup.cfg +0 -0
  17. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/__init__.py +0 -0
  18. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/__init__.pyi +0 -0
  19. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/__main__.py +0 -0
  20. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/agent_document.py +0 -0
  21. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/api.py +0 -0
  22. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/blind_eval.py +0 -0
  23. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/capabilities.py +0 -0
  24. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/compat.py +0 -0
  25. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/configuration.py +0 -0
  26. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/__init__.py +0 -0
  27. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/content.py +0 -0
  28. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/context.py +0 -0
  29. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/diff.py +0 -0
  30. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/document.py +0 -0
  31. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/formatting.py +0 -0
  32. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/handles.py +0 -0
  33. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/locations.py +0 -0
  34. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/locator.py +0 -0
  35. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/plan.py +0 -0
  36. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/resources.py +0 -0
  37. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/search.py +0 -0
  38. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/transactions.py +0 -0
  39. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/core/txn.py +0 -0
  40. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/document_state.py +0 -0
  41. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/errors.py +0 -0
  42. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/execution_lock.py +0 -0
  43. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/fastmcp_adapter.py +0 -0
  44. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/form_fill.py +0 -0
  45. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/form_output_models.py +0 -0
  46. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/__init__.py +0 -0
  47. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/_shared.py +0 -0
  48. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/agent_document.py +0 -0
  49. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/authoring.py +0 -0
  50. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/content_edit.py +0 -0
  51. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/layout_style.py +0 -0
  52. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/quality_render.py +0 -0
  53. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/read_export.py +0 -0
  54. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/specialized.py +0 -0
  55. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/tracked_changes.py +0 -0
  56. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/handlers/workflow.py +0 -0
  57. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/hwp_converter.py +0 -0
  58. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/hwp_support.py +0 -0
  59. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/identity.py +0 -0
  60. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ingest_adapters.py +0 -0
  61. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/markdown_plan.py +0 -0
  62. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/mcp_cli.py +0 -0
  63. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/metadata/tools_meta.py +0 -0
  64. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/mixed_form.py +0 -0
  65. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/mutation_models.py +0 -0
  66. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/network_policy.py +0 -0
  67. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/__init__.py +0 -0
  68. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/__init__.py +0 -0
  69. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/_batch_verification.py +0 -0
  70. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/__init__.py +0 -0
  71. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/bundle.py +0 -0
  72. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/catalog.py +0 -0
  73. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/dump.py +0 -0
  74. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/mapping.py +0 -0
  75. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/model.py +0 -0
  76. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/native.py +0 -0
  77. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/blueprint/replay.py +0 -0
  78. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/catalog.py +0 -0
  79. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/cli.py +0 -0
  80. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/commands.py +0 -0
  81. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/document.py +0 -0
  82. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/form_plan.py +0 -0
  83. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/model.py +0 -0
  84. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/path.py +0 -0
  85. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/query.py +0 -0
  86. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/agent/story.py +0 -0
  87. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/__init__.py +0 -0
  88. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/advanced_generators.py +0 -0
  89. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/builder/__init__.py +0 -0
  90. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/builder/core.py +0 -0
  91. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/builder/report.py +0 -0
  92. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/__init__.py +0 -0
  93. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/_support.py +0 -0
  94. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/composer.py +0 -0
  95. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/harvest.py +0 -0
  96. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/plan.py +0 -0
  97. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profile.py +0 -0
  98. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/body.xml +0 -0
  99. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/heading.xml +0 -0
  100. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/info_table.xml +0 -0
  101. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/title.xml +0 -0
  102. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/application_form/profile.json +0 -0
  103. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/application_form/template.hwpx +0 -0
  104. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/home_notice/fragments/body.xml +0 -0
  105. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/home_notice/fragments/heading.xml +0 -0
  106. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/home_notice/fragments/title.xml +0 -0
  107. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/home_notice/profile.json +0 -0
  108. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/home_notice/template.hwpx +0 -0
  109. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/body.xml +0 -0
  110. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/heading.xml +0 -0
  111. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/info_table.xml +0 -0
  112. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/title.xml +0 -0
  113. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/official_notice/profile.json +0 -0
  114. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/official_notice/template.hwpx +0 -0
  115. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/body.xml +0 -0
  116. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/heading.xml +0 -0
  117. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/info_table.xml +0 -0
  118. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/title.xml +0 -0
  119. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/report/profile.json +0 -0
  120. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/profiles/report/template.hwpx +0 -0
  121. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/design/validator.py +0 -0
  122. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/presets/__init__.py +0 -0
  123. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/presets/proposal.py +0 -0
  124. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/report_parser.py +0 -0
  125. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/style_profile.py +0 -0
  126. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/authoring/template_analyzer.py +0 -0
  127. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/compliance/__init__.py +0 -0
  128. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/compliance/official_lint.py +0 -0
  129. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/compliance/pii.py +0 -0
  130. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/document_ops/__init__.py +0 -0
  131. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/document_ops/comparison.py +0 -0
  132. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/document_ops/mail_merge.py +0 -0
  133. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/document_ops/redline.py +0 -0
  134. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/evalplan/__init__.py +0 -0
  135. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/evalplan/runtime.py +0 -0
  136. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/exam/__init__.py +0 -0
  137. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/exam/compose.py +0 -0
  138. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/exam/ir.py +0 -0
  139. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/exam/measure.py +0 -0
  140. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/exam/parser.py +0 -0
  141. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/exam/profile.py +0 -0
  142. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/__init__.py +0 -0
  143. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/classification.py +0 -0
  144. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fill_residue.py +0 -0
  145. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/__init__.py +0 -0
  146. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/apply.py +0 -0
  147. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/engine.py +0 -0
  148. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/measure.py +0 -0
  149. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/policy.py +0 -0
  150. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/report.py +0 -0
  151. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/seal.py +0 -0
  152. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/fit/wordbox.py +0 -0
  153. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/guidance.py +0 -0
  154. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/quality.py +0 -0
  155. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/split_run.py +0 -0
  156. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/form_fill/template_formfit.py +0 -0
  157. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/house_style/__init__.py +0 -0
  158. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/house_style/composition.py +0 -0
  159. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/house_style/data/bank.json +0 -0
  160. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/house_style/data/genres.json +0 -0
  161. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/quality/__init__.py +0 -0
  162. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/quality/page_guard.py +0 -0
  163. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/__init__.py +0 -0
  164. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/_hancom_open_rate.ps1 +0 -0
  165. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/_refresh_hwpx_mac.applescript +0 -0
  166. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/_render_hwpx.ps1 +0 -0
  167. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/_render_hwpx_mac.applescript +0 -0
  168. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/block_splits.py +0 -0
  169. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/detectors.py +0 -0
  170. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/diff.py +0 -0
  171. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/fixture_corpus.py +0 -0
  172. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/oracle.py +0 -0
  173. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/page_qa.py +0 -0
  174. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/qa_contracts.py +0 -0
  175. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/qa_metrics.py +0 -0
  176. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/rendering/worker.py +0 -0
  177. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/utilities/__init__.py +0 -0
  178. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/office/utilities/table_compute.py +0 -0
  179. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/__init__.py +0 -0
  180. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/_border_fill.py +0 -0
  181. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/composition.py +0 -0
  182. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/content_layout.py +0 -0
  183. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/context.py +0 -0
  184. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/media.py +0 -0
  185. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/memo_style.py +0 -0
  186. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/package_validation.py +0 -0
  187. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/planning.py +0 -0
  188. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/preview_export.py +0 -0
  189. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/read_query.py +0 -0
  190. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/save_policy.py +0 -0
  191. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/tables.py +0 -0
  192. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/ops_services/transactions.py +0 -0
  193. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/preview_output_models.py +0 -0
  194. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/public-modules.json +0 -0
  195. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/py.typed +0 -0
  196. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/quality.py +0 -0
  197. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/quality_generation.py +0 -0
  198. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/runtime.py +0 -0
  199. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/runtime_services.py +0 -0
  200. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/storage.py +0 -0
  201. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/upstream.py +0 -0
  202. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/utils/__init__.py +0 -0
  203. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/utils/helpers.py +0 -0
  204. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/visual_qa.py +0 -0
  205. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/__init__.py +0 -0
  206. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/adapters.py +0 -0
  207. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/dispatcher.py +0 -0
  208. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/models.py +0 -0
  209. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/policy.py +0 -0
  210. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/render_contracts.py +0 -0
  211. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/render_metrics.py +0 -0
  212. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/render_queue.py +0 -0
  213. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/render_security.py +0 -0
  214. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/render_transport.py +0 -0
  215. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/rendering.py +0 -0
  216. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/service.py +0 -0
  217. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/state_machine.py +0 -0
  218. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workflow/store.py +0 -0
  219. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/hwpx_automation/workspace.py +0 -0
  220. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/python_hwpx_automation.egg-info/SOURCES.txt +0 -0
  221. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/python_hwpx_automation.egg-info/dependency_links.txt +0 -0
  222. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/python_hwpx_automation.egg-info/entry_points.txt +0 -0
  223. {python_hwpx_automation-6.0.4 → python_hwpx_automation-6.1.3}/src/python_hwpx_automation.egg-info/top_level.txt +0 -0
@@ -1,21 +1,26 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-hwpx-automation
3
- Version: 6.0.4
3
+ Version: 6.1.3
4
4
  Summary: Task-oriented HWPX document automation for Python, with an optional MCP adapter.
5
5
  Author: Kohkyuhyun
6
6
  License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/airmang/python-hwpx-automation
8
8
  Project-URL: Issues, https://github.com/airmang/python-hwpx-automation/issues
9
9
  Keywords: hwpx,hancom,document-automation,workflow,mcp,ai-agent
10
+ Classifier: Intended Audience :: Developers
10
11
  Classifier: Programming Language :: Python :: 3
11
12
  Classifier: Programming Language :: Python :: 3.10
12
13
  Classifier: Programming Language :: Python :: 3.11
13
14
  Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Typing :: Typed
14
19
  Requires-Python: >=3.10
15
20
  Description-Content-Type: text/markdown
16
21
  License-File: LICENSE
17
22
  License-File: NOTICE
18
- Requires-Dist: python-hwpx<6,>=5.0.0
23
+ Requires-Dist: python-hwpx<6,>=5.1.0
19
24
  Requires-Dist: pydantic<3,>=2.11
20
25
  Requires-Dist: cryptography>=42.0
21
26
  Requires-Dist: anyio>=4.0
@@ -68,41 +73,29 @@ Dynamic: license-file
68
73
  </p>
69
74
 
70
75
  <!-- release-state: release-approved -->
71
- > [!WARNING]
72
- > **릴리스 상태 `release-approved`: 6.0.4 train 발행이 승인되어 진행
73
- > 중입니다(2026-07-28).** checkout은
74
- > `python-hwpx 5.0.1 → python-hwpx-automation 6.0.4 → hwpx-plugin 1.0.0`
75
- > train과 계약 해시 `0ce938371f0b55a6`을 설명하지만, **원격 truth는 아직
76
- > 관찰 전**입니다. 마지막으로 plugin 설치까지 함께 검증한 완전한 공개
77
- > 트레인은 여전히
78
- > `python-hwpx 4.2.0 → hwpx-mcp-server 5.1.0 → hwpx-plugin 0.8.0`,
79
- > 계약 해시 `429cb6706323e762`입니다. 아래 canonical 설치 명령은 발행
80
- > readback이 끝나기 전에는 공개 설치로 간주하지 마세요.
81
- > 상태 승격은 `unreleased-candidate release-approved released` 세 단계이며,
82
- > `released`와 current-public 좌표는 core·canonical·compatibilityplugin GitHub
83
- > Release·marketplace·실제 marketplace 설치까지 3스택 전체 원격 정본을 관찰한 뒤
84
- > 후속 commit에서만 바꿉니다. 절차는
85
- > [릴리스 상태 runbook](docs/release-runbook.md)에 있습니다.
86
-
87
- [python-hwpx](https://github.com/airmang/python-hwpx)의 format/object-model 위에서
88
- 저작·양식 채움·시험지 조판·평가계획·안전한 에이전트 워크플로를 제공합니다.
89
- 기본 설치는 MCP SDK 없이 Python API와 `hwpx` CLI를 사용할 수 있습니다.
90
- [모델 컨텍스트 프로토콜(MCP)](https://modelcontextprotocol.io)은 `[mcp]` extra로
91
- 추가하는 선택 어댑터입니다.
92
-
93
- 한컴오피스도 Windows도 필요하지 않으므로 **ChatGPT 채팅 환경에서도 HWPX
94
- 문서를 다룰 수 있습니다.** 파이썬이 도는 곳이면 저작·양식 채움 워크플로가
95
- 그대로 동작합니다.
96
-
97
- | 계층 | 저장소 | 정본 책임 |
76
+ > [!NOTE]
77
+ > 소스 트리는 아직 공개되지 않은 6.1.3 후보입니다(누름틀 필드 저작
78
+ > `add_form_field`, 계약 `ac1a422376b5ac84`, 128 도구). 현재 공개 트레인은
79
+ > `python-hwpx 5.0.2 → python-hwpx-automation 6.0.4 → hwpx-plugin 1.0.1`
80
+ > (계약 `0ce938371f0b55a6`)입니다. core·automation PyPI와 plugin GitHub
81
+ > Release·marketplace·실제 marketplace 설치까지 확인한 승격하며, 기존
82
+ > 5.x 설치는 별도 발행된 `hwpx-mcp-server 5.1.1`이 보호합니다. 절차와 상태
83
+ > 머신: [릴리스 runbook](docs/release-runbook.md)
84
+
85
+ [python-hwpx](https://github.com/airmang/python-hwpx) 엔진 위에서 문서 저작·
86
+ 양식 채움·시험지 조판·안전한 에이전트 워크플로를 제공하는 응용 계층입니다.
87
+ 기본 설치는 MCP 없이 Python API`hwpx` CLI로 쓰고,
88
+ [모델 컨텍스트 프로토콜(MCP)](https://modelcontextprotocol.io) 서버는 필요할
89
+ `[mcp]` extra로 더합니다. 한컴오피스도 Windows도 필요 없으므로 **파이썬이 도는
90
+ ChatGPT 채팅 안에서도** 그대로 동작합니다.
91
+
92
+ | | 저장소 | 역할 |
98
93
  |---|---|---|
99
- | Core | [`python-hwpx`](https://github.com/airmang/python-hwpx) | HWPX package/object model·OPC/OXML·직렬화·재사용 primitive |
100
- | Automation | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation) | Python 자동화·워크플로·profile/policy·렌더·선택형 MCP adapter |
101
- | Judgment | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) | 에이전트 intent/genre 판단·ambiguity 처리·plugin/skill 가이드 |
94
+ | 📦 | [`python-hwpx`](https://github.com/airmang/python-hwpx) | HWPX 문서를 읽고·고치고·만드는 순수 파이썬 엔진 |
95
+ | 🔌 | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation) | 저작·양식 채움 워크플로, `hwpx` CLI, 선택형 MCP 서버 |
96
+ | 🎯 | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) | 에이전트가 알맞은 도구를 고르도록 돕는 플러그인/스킬 번들 |
102
97
 
103
- 저장소는 표의 Automation 정본입니다.
104
-
105
- ## Python 자동화 시작하기 (6.0 후보)
98
+ ## Python 자동화 시작하기
106
99
 
107
100
  ```bash
108
101
  pip install python-hwpx-automation
@@ -123,17 +116,13 @@ document.save_to_path("meeting-result.hwpx")
123
116
 
124
117
  `python -m hwpx_automation --help`와 `hwpx help`는 같은 task CLI를 실행합니다.
125
118
 
126
- ## MCP 어댑터 시작하기 (6.0 후보)
119
+ ## MCP 어댑터 시작하기
127
120
 
128
121
  ```bash
129
122
  pip install "python-hwpx-automation[mcp]"
130
123
  hwpx-automation-mcp
131
124
  ```
132
125
 
133
- 6.x 호환 기간에는 `pip install hwpx-mcp-server`와 `hwpx-mcp-server`도
134
- 동작합니다. 옛 distribution/import/console 제거는 7.0 이전에는 하지 않으며,
135
- 최소 90일 공개 관찰과 별도 오너 승인이 필요합니다.
136
-
137
126
  MCP 클라이언트 설정 파일에 아래 블록 하나면 `hwpx` 서버를 잡습니다 — Claude Desktop은
138
127
  `claude_desktop_config.json`, VS Code는 `.vscode/mcp.json`(키가 `mcpServers` 대신 `servers`),
139
128
  Gemini CLI는 `~/.gemini/settings.json`, Cursor·Windsurf는 각 에디터의 MCP 설정 파일입니다.
@@ -156,16 +145,18 @@ Gemini CLI는 `~/.gemini/settings.json`, Cursor·Windsurf는 각 에디터의 MC
156
145
  }
157
146
  ```
158
147
 
159
- `HWPX_AUTOMATION_WORKSPACE_ROOTS`에는 문서가 있는 폴더(절대경로 또는 `~`)를 지정하세요. Windows는
160
- `"[\"C:\\\\hwpx\"]"`처럼 씁니다. 값을 비워 두면 서버는 실행 위치(cwd)를 root로 쓰려 하지만,
161
- Claude Desktop 같은 GUI 클라이언트는 서버를 시스템 디렉터리(Windows `C:\Windows\System32`,
162
- macOS `/`)에서 띄우므로 이런 degenerate cwd는 거부되고 모든 문서 경로가 막힙니다. 그래서 처음부터
163
- 이 값을 설정하는 것을 권장합니다. 나머지 옵션은 [환경 변수](#환경-변수) 표를 참고하세요.
148
+ `HWPX_AUTOMATION_WORKSPACE_ROOTS`에는 문서가 있는 폴더(절대경로 또는 `~`)를
149
+ 지정하세요. Windows는 `"[\"C:\\\\hwpx\"]"`처럼 씁니다. 값을 비워 두면 GUI
150
+ 클라이언트는 서버를 시스템 디렉터리에서 띄우기 때문에 모든 문서 경로가
151
+ 막힙니다 처음부터 지정하는 것을 권장합니다. 나머지 옵션은
152
+ [환경 변수](#환경-변수) 표를 참고하세요.
164
153
 
165
154
  > 비-HWPX 문서(PDF/DOCX/XLSX/HTML/TXT)를 `document_to_markdown`으로 읽으려면
166
- > `pip install "python-hwpx-automation[ingest]"`(또는 이름 `"hwpx-mcp-server[ingest]"`)로
167
- > MarkItDown adapter를 함께 설치합니다.
168
- > 요구 사항: `Python >= 3.10` · `python-hwpx >= 5.0.0`.
155
+ > `pip install "python-hwpx-automation[ingest]"`로 MarkItDown adapter를 함께
156
+ > 설치합니다. 요구 사항: `Python >= 3.10` · `python-hwpx >= 5.0.0`.
157
+
158
+ 기존 `hwpx-mcp-server` 배포·import·콘솔·설정 키도 6.x 동안 그대로 동작합니다 —
159
+ 전체 목록과 유지 규칙: [6.x 호환 표면](docs/compatibility-6x.md)
169
160
 
170
161
  ## 무엇을 하나
171
162
 
@@ -180,34 +171,22 @@ macOS `/`)에서 띄우므로 이런 degenerate cwd는 거부되고 모든 문
180
171
 
181
172
  자세한 내용: [사용 사례](docs/use-cases.md) · [스킬 우선 워크플로](docs/skill-first-workflows.md)
182
173
 
183
- ### 하나의 흐름부터
184
-
185
- 처음부터 모든 도구를 외울 필요는 없습니다. 보통 아래 하나로 시작합니다.
174
+ ## 안전하게 쓰는 법
186
175
 
187
- 1. **읽기** `get_document_info` `get_document_outline`/`get_document_text` `find_text`, `get_table_map`으로 필요한 부분만. (저장하지 않음)
188
- 2. **안전 수정** — `copy_document`로 사본 생성 → 읽기 도구로 대상 확인 → `search_and_replace`, `set_table_cell_text` 같은 전문 도구나 `apply_document_commands`로 가장 작은 변경 → 다시 읽어 확인 → 검토가 끝난 복사본을 handoff.
176
+ 처음부터 모든 도구를 외울 필요는 없습니다. 보통 이렇게 흘러갑니다.
189
177
 
190
- 핵심은 **copy first · smallest edit · re-read after edits**입니다.
178
+ 1. **읽기** `get_document_info` `get_document_outline`/`get_document_text` `find_text`, `get_table_map`으로 필요한 부분만 파악합니다. (저장하지 않음)
179
+ 2. **안전 수정** — `copy_document`로 사본을 만들고, 가장 작은 변경(`search_and_replace`, `set_table_cell_text`, `apply_document_commands`)을 적용한 뒤 다시 읽어 확인하고, 검토가 끝난 사본을 전달합니다.
191
180
 
192
- ## 안전과 품질 게이트
181
+ 핵심은 **copy first · smallest edit · re-read after edits**입니다. 수정 도구는
182
+ 호출 즉시 저장되므로 검토용 작업은 반드시 사본에서 하세요.
193
183
 
194
- - **read first** 먼저 읽기 도구로 문서를 파악합니다.
195
- - **copy before risky edits** — 결과물을 보존해야 하면 `copy_document`를 먼저 호출합니다.
196
- - **mutating tools persist immediately** 수정 도구는 호출 즉시 저장되므로 검토용은 복사본에서 작업합니다.
197
- - **explicit handoff uses the reviewed copy** — 납품·handoff검토가 끝난 복사본 파일 기준입니다.
198
-
199
- 모델은 operation/plan만 보내고 raw XML을 직접 편집하지 않습니다. 일반 저장 경로는 python-hwpx의
200
- 단일 `SavePipeline` 게이트를 통과해 무결성·XML·OPC/ID·열림안전을 검사하고, `quality`에 따라
201
- `visualComplete` 블록(`ok`·`status`·`errorCodes`)을 응답에 실으며, 게이트가 실패하면 아무것도 쓰지 않고
202
- 소유 후보만 원복합니다. capability handshake가 core/automation/plugin
203
- 버전+해시 skew를 fail-closed로 차단합니다. 6.x 응답의 `versions.mcp`와
204
- `minMcpVersion`은 기존 소비자를 위한 alias로만 유지됩니다.
205
- 같은 이유로 `MIN_MCP_VERSION`, 공개 오류 schema `hwpx.mcp-error/v1`,
206
- 동결된 architecture receipt ID `hwpx-mcp.*`, parity receipt 필드
207
- `mcpRuntimeMembers`도 6.x에서 정확히 보존합니다. canonical 표기는
208
- `versions.automation`·`minAutomationVersion`·`MIN_AUTOMATION_VERSION`이며,
209
- 보존된 MCP 철자는 제품 소유권이 아니라 wire/receipt 호환 식별자입니다.
210
- 보안 상세는 [하드닝 가이드](docs/hardening_guide_ko.md)에 있습니다.
184
+ 모델은 operation/plan만 보내고 raw XML을 직접 편집하지 않습니다. 일반 저장
185
+ 경로는 python-hwpx의 단일 `SavePipeline` 게이트를 통과해 무결성·XML·OPC/ID·
186
+ 열림안전을 검사하고, 게이트가 실패하면 아무것도 쓰지 않습니다. capability
187
+ handshakecore/automation/plugin 버전+해시 skew를 fail-closed로 차단합니다.
188
+ 보안 상세: [하드닝 가이드](docs/hardening_guide_ko.md) · 옛 이름과의 호환
189
+ 식별자: [6.x 호환 표면](docs/compatibility-6x.md)
211
190
 
212
191
  > **위치 계약** — `paragraph_index`는 본문 직속 문단의 0-based 인덱스입니다. 표 안 문단은 여기 섞지 않고
213
192
  > `{"kind":"table_cell_paragraph","table_index":0,"row":0,"col":1,"cell_paragraph_index":0}` 같은 `location`
@@ -228,23 +207,10 @@ macOS `/`)에서 띄우므로 이런 degenerate cwd는 거부되고 모든 문
228
207
  | `HWPX_AUTOMATION_WORKFLOW_STORE` | durable workflow SQLite 경로. 기존 `HWPX_WORKFLOW_STORE`보다 우선 | 기존 6.x 상태 경로 |
229
208
  | `LOG_LEVEL` | 로그 레벨 | `INFO` |
230
209
 
231
- 동일 suffix의 기존 `HWPX_MCP_*` 키는 6.x 동안 fallback으로 유지됩니다.
232
- 두 키가 함께 있으면 `HWPX_AUTOMATION_*`이 우선합니다. workflow DB의 기존
233
- `.../hwpx-mcp-server/workflows.sqlite3` 기본 경로도 6.x에서는 데이터 유실을
234
- 막기 위해 그대로 사용합니다.
235
-
236
- 제품-neutral integration/capability 키는 옛 MCP 제품명을 담지 않으므로 이름을
237
- 바꾸지 않습니다.
238
-
239
- | 분류 | 보존하는 정확한 키 |
240
- |---|---|
241
- | render integration | `HWPX_RENDER_QUEUE_ROOT`, `HWPX_RENDER_QUEUE_URL`, `HWPX_RENDER_QUEUE_SECRET`, `HWPX_RENDER_TRANSPORT_AUTH`, `HWPX_RENDER_CA_FILE`, `HWPX_RENDER_CLIENT_CERT_FILE`, `HWPX_RENDER_CLIENT_KEY_FILE` |
242
- | workflow security | `HWPX_WORKFLOW_ENCRYPTION_KEY` |
243
- | oracle capability | `HWPX_ORACLE_STRUCTURAL_ONLY`, `HWPX_ORACLE_BUDGET_SECONDS` |
244
- | plugin integration | `HWPX_SKILL_VERSION`, `HWPX_PLUGIN_ROOT` |
245
-
246
- 이 키들은 `integration-preserved` 또는 `capability-preserved` 정본이며
247
- `HWPX_AUTOMATION_*` alias를 새로 만들지 않습니다.
210
+ 동일 suffix의 기존 `HWPX_MCP_*` 키는 6.x 동안 fallback으로 유지되며, 두 키가
211
+ 함께 있으면 `HWPX_AUTOMATION_*`이 우선합니다. render·workflow·oracle·plugin
212
+ 연동용 보존 전체 목록과 workflow DB 경로 규칙은
213
+ [6.x 호환 표면](docs/compatibility-6x.md)에 있습니다.
248
214
 
249
215
  경로는 기본적으로 workspace 밖 traversal과 symlink escape를 거부하고, URL 입력은 HTTPS·공개 IP만
250
216
  허용합니다. 원자 rename을 제공하지 않는 호스트의 동시성 주의사항은 [하드닝 가이드](docs/hardening_guide_ko.md)를 보세요.
@@ -262,8 +228,6 @@ python -m pip install -e ".[test]" # 테스트 의존성
262
228
  python -m pytest -q # 전체 테스트
263
229
  python scripts/run_conformance.py run \
264
230
  --tier structural --check tests/conformance/golden/structural.json
265
- # 공개 합성 코퍼스를 다시 만들 때만:
266
- python scripts/conformance_corpus_build.py
267
231
  ```
268
232
 
269
233
  ## 감사의 말
@@ -13,41 +13,29 @@
13
13
  </p>
14
14
 
15
15
  <!-- release-state: release-approved -->
16
- > [!WARNING]
17
- > **릴리스 상태 `release-approved`: 6.0.4 train 발행이 승인되어 진행
18
- > 중입니다(2026-07-28).** checkout은
19
- > `python-hwpx 5.0.1 → python-hwpx-automation 6.0.4 → hwpx-plugin 1.0.0`
20
- > train과 계약 해시 `0ce938371f0b55a6`을 설명하지만, **원격 truth는 아직
21
- > 관찰 전**입니다. 마지막으로 plugin 설치까지 함께 검증한 완전한 공개
22
- > 트레인은 여전히
23
- > `python-hwpx 4.2.0 → hwpx-mcp-server 5.1.0 → hwpx-plugin 0.8.0`,
24
- > 계약 해시 `429cb6706323e762`입니다. 아래 canonical 설치 명령은 발행
25
- > readback이 끝나기 전에는 공개 설치로 간주하지 마세요.
26
- > 상태 승격은 `unreleased-candidate release-approved released` 세 단계이며,
27
- > `released`와 current-public 좌표는 core·canonical·compatibilityplugin GitHub
28
- > Release·marketplace·실제 marketplace 설치까지 3스택 전체 원격 정본을 관찰한 뒤
29
- > 후속 commit에서만 바꿉니다. 절차는
30
- > [릴리스 상태 runbook](docs/release-runbook.md)에 있습니다.
31
-
32
- [python-hwpx](https://github.com/airmang/python-hwpx)의 format/object-model 위에서
33
- 저작·양식 채움·시험지 조판·평가계획·안전한 에이전트 워크플로를 제공합니다.
34
- 기본 설치는 MCP SDK 없이 Python API와 `hwpx` CLI를 사용할 수 있습니다.
35
- [모델 컨텍스트 프로토콜(MCP)](https://modelcontextprotocol.io)은 `[mcp]` extra로
36
- 추가하는 선택 어댑터입니다.
37
-
38
- 한컴오피스도 Windows도 필요하지 않으므로 **ChatGPT 채팅 환경에서도 HWPX
39
- 문서를 다룰 수 있습니다.** 파이썬이 도는 곳이면 저작·양식 채움 워크플로가
40
- 그대로 동작합니다.
41
-
42
- | 계층 | 저장소 | 정본 책임 |
16
+ > [!NOTE]
17
+ > 소스 트리는 아직 공개되지 않은 6.1.3 후보입니다(누름틀 필드 저작
18
+ > `add_form_field`, 계약 `ac1a422376b5ac84`, 128 도구). 현재 공개 트레인은
19
+ > `python-hwpx 5.0.2 → python-hwpx-automation 6.0.4 → hwpx-plugin 1.0.1`
20
+ > (계약 `0ce938371f0b55a6`)입니다. core·automation PyPI와 plugin GitHub
21
+ > Release·marketplace·실제 marketplace 설치까지 확인한 승격하며, 기존
22
+ > 5.x 설치는 별도 발행된 `hwpx-mcp-server 5.1.1`이 보호합니다. 절차와 상태
23
+ > 머신: [릴리스 runbook](docs/release-runbook.md)
24
+
25
+ [python-hwpx](https://github.com/airmang/python-hwpx) 엔진 위에서 문서 저작·
26
+ 양식 채움·시험지 조판·안전한 에이전트 워크플로를 제공하는 응용 계층입니다.
27
+ 기본 설치는 MCP 없이 Python API`hwpx` CLI로 쓰고,
28
+ [모델 컨텍스트 프로토콜(MCP)](https://modelcontextprotocol.io) 서버는 필요할
29
+ `[mcp]` extra로 더합니다. 한컴오피스도 Windows도 필요 없으므로 **파이썬이 도는
30
+ ChatGPT 채팅 안에서도** 그대로 동작합니다.
31
+
32
+ | | 저장소 | 역할 |
43
33
  |---|---|---|
44
- | Core | [`python-hwpx`](https://github.com/airmang/python-hwpx) | HWPX package/object model·OPC/OXML·직렬화·재사용 primitive |
45
- | Automation | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation) | Python 자동화·워크플로·profile/policy·렌더·선택형 MCP adapter |
46
- | Judgment | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) | 에이전트 intent/genre 판단·ambiguity 처리·plugin/skill 가이드 |
34
+ | 📦 | [`python-hwpx`](https://github.com/airmang/python-hwpx) | HWPX 문서를 읽고·고치고·만드는 순수 파이썬 엔진 |
35
+ | 🔌 | [`python-hwpx-automation`](https://github.com/airmang/python-hwpx-automation) | 저작·양식 채움 워크플로, `hwpx` CLI, 선택형 MCP 서버 |
36
+ | 🎯 | [`hwpx-plugins`](https://github.com/airmang/hwpx-plugins) | 에이전트가 알맞은 도구를 고르도록 돕는 플러그인/스킬 번들 |
47
37
 
48
- 저장소는 표의 Automation 정본입니다.
49
-
50
- ## Python 자동화 시작하기 (6.0 후보)
38
+ ## Python 자동화 시작하기
51
39
 
52
40
  ```bash
53
41
  pip install python-hwpx-automation
@@ -68,17 +56,13 @@ document.save_to_path("meeting-result.hwpx")
68
56
 
69
57
  `python -m hwpx_automation --help`와 `hwpx help`는 같은 task CLI를 실행합니다.
70
58
 
71
- ## MCP 어댑터 시작하기 (6.0 후보)
59
+ ## MCP 어댑터 시작하기
72
60
 
73
61
  ```bash
74
62
  pip install "python-hwpx-automation[mcp]"
75
63
  hwpx-automation-mcp
76
64
  ```
77
65
 
78
- 6.x 호환 기간에는 `pip install hwpx-mcp-server`와 `hwpx-mcp-server`도
79
- 동작합니다. 옛 distribution/import/console 제거는 7.0 이전에는 하지 않으며,
80
- 최소 90일 공개 관찰과 별도 오너 승인이 필요합니다.
81
-
82
66
  MCP 클라이언트 설정 파일에 아래 블록 하나면 `hwpx` 서버를 잡습니다 — Claude Desktop은
83
67
  `claude_desktop_config.json`, VS Code는 `.vscode/mcp.json`(키가 `mcpServers` 대신 `servers`),
84
68
  Gemini CLI는 `~/.gemini/settings.json`, Cursor·Windsurf는 각 에디터의 MCP 설정 파일입니다.
@@ -101,16 +85,18 @@ Gemini CLI는 `~/.gemini/settings.json`, Cursor·Windsurf는 각 에디터의 MC
101
85
  }
102
86
  ```
103
87
 
104
- `HWPX_AUTOMATION_WORKSPACE_ROOTS`에는 문서가 있는 폴더(절대경로 또는 `~`)를 지정하세요. Windows는
105
- `"[\"C:\\\\hwpx\"]"`처럼 씁니다. 값을 비워 두면 서버는 실행 위치(cwd)를 root로 쓰려 하지만,
106
- Claude Desktop 같은 GUI 클라이언트는 서버를 시스템 디렉터리(Windows `C:\Windows\System32`,
107
- macOS `/`)에서 띄우므로 이런 degenerate cwd는 거부되고 모든 문서 경로가 막힙니다. 그래서 처음부터
108
- 이 값을 설정하는 것을 권장합니다. 나머지 옵션은 [환경 변수](#환경-변수) 표를 참고하세요.
88
+ `HWPX_AUTOMATION_WORKSPACE_ROOTS`에는 문서가 있는 폴더(절대경로 또는 `~`)를
89
+ 지정하세요. Windows는 `"[\"C:\\\\hwpx\"]"`처럼 씁니다. 값을 비워 두면 GUI
90
+ 클라이언트는 서버를 시스템 디렉터리에서 띄우기 때문에 모든 문서 경로가
91
+ 막힙니다 처음부터 지정하는 것을 권장합니다. 나머지 옵션은
92
+ [환경 변수](#환경-변수) 표를 참고하세요.
109
93
 
110
94
  > 비-HWPX 문서(PDF/DOCX/XLSX/HTML/TXT)를 `document_to_markdown`으로 읽으려면
111
- > `pip install "python-hwpx-automation[ingest]"`(또는 이름 `"hwpx-mcp-server[ingest]"`)로
112
- > MarkItDown adapter를 함께 설치합니다.
113
- > 요구 사항: `Python >= 3.10` · `python-hwpx >= 5.0.0`.
95
+ > `pip install "python-hwpx-automation[ingest]"`로 MarkItDown adapter를 함께
96
+ > 설치합니다. 요구 사항: `Python >= 3.10` · `python-hwpx >= 5.0.0`.
97
+
98
+ 기존 `hwpx-mcp-server` 배포·import·콘솔·설정 키도 6.x 동안 그대로 동작합니다 —
99
+ 전체 목록과 유지 규칙: [6.x 호환 표면](docs/compatibility-6x.md)
114
100
 
115
101
  ## 무엇을 하나
116
102
 
@@ -125,34 +111,22 @@ macOS `/`)에서 띄우므로 이런 degenerate cwd는 거부되고 모든 문
125
111
 
126
112
  자세한 내용: [사용 사례](docs/use-cases.md) · [스킬 우선 워크플로](docs/skill-first-workflows.md)
127
113
 
128
- ### 하나의 흐름부터
129
-
130
- 처음부터 모든 도구를 외울 필요는 없습니다. 보통 아래 하나로 시작합니다.
114
+ ## 안전하게 쓰는 법
131
115
 
132
- 1. **읽기** `get_document_info` `get_document_outline`/`get_document_text` `find_text`, `get_table_map`으로 필요한 부분만. (저장하지 않음)
133
- 2. **안전 수정** — `copy_document`로 사본 생성 → 읽기 도구로 대상 확인 → `search_and_replace`, `set_table_cell_text` 같은 전문 도구나 `apply_document_commands`로 가장 작은 변경 → 다시 읽어 확인 → 검토가 끝난 복사본을 handoff.
116
+ 처음부터 모든 도구를 외울 필요는 없습니다. 보통 이렇게 흘러갑니다.
134
117
 
135
- 핵심은 **copy first · smallest edit · re-read after edits**입니다.
118
+ 1. **읽기** `get_document_info` `get_document_outline`/`get_document_text` `find_text`, `get_table_map`으로 필요한 부분만 파악합니다. (저장하지 않음)
119
+ 2. **안전 수정** — `copy_document`로 사본을 만들고, 가장 작은 변경(`search_and_replace`, `set_table_cell_text`, `apply_document_commands`)을 적용한 뒤 다시 읽어 확인하고, 검토가 끝난 사본을 전달합니다.
136
120
 
137
- ## 안전과 품질 게이트
121
+ 핵심은 **copy first · smallest edit · re-read after edits**입니다. 수정 도구는
122
+ 호출 즉시 저장되므로 검토용 작업은 반드시 사본에서 하세요.
138
123
 
139
- - **read first** 먼저 읽기 도구로 문서를 파악합니다.
140
- - **copy before risky edits** — 결과물을 보존해야 하면 `copy_document`를 먼저 호출합니다.
141
- - **mutating tools persist immediately** 수정 도구는 호출 즉시 저장되므로 검토용은 복사본에서 작업합니다.
142
- - **explicit handoff uses the reviewed copy** — 납품·handoff검토가 끝난 복사본 파일 기준입니다.
143
-
144
- 모델은 operation/plan만 보내고 raw XML을 직접 편집하지 않습니다. 일반 저장 경로는 python-hwpx의
145
- 단일 `SavePipeline` 게이트를 통과해 무결성·XML·OPC/ID·열림안전을 검사하고, `quality`에 따라
146
- `visualComplete` 블록(`ok`·`status`·`errorCodes`)을 응답에 실으며, 게이트가 실패하면 아무것도 쓰지 않고
147
- 소유 후보만 원복합니다. capability handshake가 core/automation/plugin
148
- 버전+해시 skew를 fail-closed로 차단합니다. 6.x 응답의 `versions.mcp`와
149
- `minMcpVersion`은 기존 소비자를 위한 alias로만 유지됩니다.
150
- 같은 이유로 `MIN_MCP_VERSION`, 공개 오류 schema `hwpx.mcp-error/v1`,
151
- 동결된 architecture receipt ID `hwpx-mcp.*`, parity receipt 필드
152
- `mcpRuntimeMembers`도 6.x에서 정확히 보존합니다. canonical 표기는
153
- `versions.automation`·`minAutomationVersion`·`MIN_AUTOMATION_VERSION`이며,
154
- 보존된 MCP 철자는 제품 소유권이 아니라 wire/receipt 호환 식별자입니다.
155
- 보안 상세는 [하드닝 가이드](docs/hardening_guide_ko.md)에 있습니다.
124
+ 모델은 operation/plan만 보내고 raw XML을 직접 편집하지 않습니다. 일반 저장
125
+ 경로는 python-hwpx의 단일 `SavePipeline` 게이트를 통과해 무결성·XML·OPC/ID·
126
+ 열림안전을 검사하고, 게이트가 실패하면 아무것도 쓰지 않습니다. capability
127
+ handshakecore/automation/plugin 버전+해시 skew를 fail-closed로 차단합니다.
128
+ 보안 상세: [하드닝 가이드](docs/hardening_guide_ko.md) · 옛 이름과의 호환
129
+ 식별자: [6.x 호환 표면](docs/compatibility-6x.md)
156
130
 
157
131
  > **위치 계약** — `paragraph_index`는 본문 직속 문단의 0-based 인덱스입니다. 표 안 문단은 여기 섞지 않고
158
132
  > `{"kind":"table_cell_paragraph","table_index":0,"row":0,"col":1,"cell_paragraph_index":0}` 같은 `location`
@@ -173,23 +147,10 @@ macOS `/`)에서 띄우므로 이런 degenerate cwd는 거부되고 모든 문
173
147
  | `HWPX_AUTOMATION_WORKFLOW_STORE` | durable workflow SQLite 경로. 기존 `HWPX_WORKFLOW_STORE`보다 우선 | 기존 6.x 상태 경로 |
174
148
  | `LOG_LEVEL` | 로그 레벨 | `INFO` |
175
149
 
176
- 동일 suffix의 기존 `HWPX_MCP_*` 키는 6.x 동안 fallback으로 유지됩니다.
177
- 두 키가 함께 있으면 `HWPX_AUTOMATION_*`이 우선합니다. workflow DB의 기존
178
- `.../hwpx-mcp-server/workflows.sqlite3` 기본 경로도 6.x에서는 데이터 유실을
179
- 막기 위해 그대로 사용합니다.
180
-
181
- 제품-neutral integration/capability 키는 옛 MCP 제품명을 담지 않으므로 이름을
182
- 바꾸지 않습니다.
183
-
184
- | 분류 | 보존하는 정확한 키 |
185
- |---|---|
186
- | render integration | `HWPX_RENDER_QUEUE_ROOT`, `HWPX_RENDER_QUEUE_URL`, `HWPX_RENDER_QUEUE_SECRET`, `HWPX_RENDER_TRANSPORT_AUTH`, `HWPX_RENDER_CA_FILE`, `HWPX_RENDER_CLIENT_CERT_FILE`, `HWPX_RENDER_CLIENT_KEY_FILE` |
187
- | workflow security | `HWPX_WORKFLOW_ENCRYPTION_KEY` |
188
- | oracle capability | `HWPX_ORACLE_STRUCTURAL_ONLY`, `HWPX_ORACLE_BUDGET_SECONDS` |
189
- | plugin integration | `HWPX_SKILL_VERSION`, `HWPX_PLUGIN_ROOT` |
190
-
191
- 이 키들은 `integration-preserved` 또는 `capability-preserved` 정본이며
192
- `HWPX_AUTOMATION_*` alias를 새로 만들지 않습니다.
150
+ 동일 suffix의 기존 `HWPX_MCP_*` 키는 6.x 동안 fallback으로 유지되며, 두 키가
151
+ 함께 있으면 `HWPX_AUTOMATION_*`이 우선합니다. render·workflow·oracle·plugin
152
+ 연동용 보존 전체 목록과 workflow DB 경로 규칙은
153
+ [6.x 호환 표면](docs/compatibility-6x.md)에 있습니다.
193
154
 
194
155
  경로는 기본적으로 workspace 밖 traversal과 symlink escape를 거부하고, URL 입력은 HTTPS·공개 IP만
195
156
  허용합니다. 원자 rename을 제공하지 않는 호스트의 동시성 주의사항은 [하드닝 가이드](docs/hardening_guide_ko.md)를 보세요.
@@ -207,8 +168,6 @@ python -m pip install -e ".[test]" # 테스트 의존성
207
168
  python -m pytest -q # 전체 테스트
208
169
  python scripts/run_conformance.py run \
209
170
  --tier structural --check tests/conformance/golden/structural.json
210
- # 공개 합성 코퍼스를 다시 만들 때만:
211
- python scripts/conformance_corpus_build.py
212
171
  ```
213
172
 
214
173
  ## 감사의 말
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-hwpx-automation"
7
- version = "6.0.4"
7
+ version = "6.1.3"
8
8
  description = "Task-oriented HWPX document automation for Python, with an optional MCP adapter."
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Kohkyuhyun" }]
@@ -13,10 +13,15 @@ license-files = ["LICENSE", "NOTICE"]
13
13
  requires-python = ">=3.10"
14
14
  keywords = ["hwpx", "hancom", "document-automation", "workflow", "mcp", "ai-agent"]
15
15
  classifiers = [
16
+ "Intended Audience :: Developers",
16
17
  "Programming Language :: Python :: 3",
17
18
  "Programming Language :: Python :: 3.10",
18
19
  "Programming Language :: Python :: 3.11",
19
20
  "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
23
+ "Topic :: Software Development :: Libraries",
24
+ "Typing :: Typed",
20
25
  ]
21
26
  dependencies = [
22
27
  # 5.0 is the floor, not a preference: this package declares the `hwpx` console
@@ -24,7 +29,7 @@ dependencies = [
24
29
  # the bounded major here is what makes "no valid install has two declarers"
25
30
  # true rather than hopeful, and prevents the next core major from silently
26
31
  # breaking an already-published automation line.
27
- "python-hwpx>=5.0.0,<6", # HWPX object model, OXML/OPC, format-native primitives
32
+ "python-hwpx>=5.1.0,<6", # HWPX object model, OXML/OPC, format-native primitives
28
33
 
29
34
  "pydantic>=2.11,<3",
30
35
  "cryptography>=42.0",
@@ -381,6 +381,39 @@ def list_form_fields(filename: str) -> dict:
381
381
  return _with_document_state(RUNTIME_SERVICES.ops.list_form_fields(path), path)
382
382
 
383
383
 
384
+ def add_form_field(
385
+ filename: str,
386
+ name: str,
387
+ prompt: str = "",
388
+ memo: str = "",
389
+ paragraph_index: int = None,
390
+ table_index: int = None,
391
+ row: int = None,
392
+ col: int = None,
393
+ dry_run: bool = False,
394
+ expected_revision: str = None,
395
+ ) -> dict:
396
+ """누름틀(click-here) 필드를 생성합니다. 실한컴 CLICKHERE 형상 그대로 방출되어
397
+ 기존 list/fill/한컴이 특수분기 없이 소비합니다. prompt(안내문)는 화면 전용(미인쇄).
398
+ 배치: 기본=문서 끝 새 문단, paragraph_index=기존 문단, tableIndex+row+col=표 셀."""
399
+ path = resolve_path(filename)
400
+ guard = _revision_guard(path, expected_revision)
401
+ if guard is not None:
402
+ return guard
403
+ result = RUNTIME_SERVICES.ops.add_form_field(
404
+ path,
405
+ name=name,
406
+ prompt=prompt,
407
+ memo=memo,
408
+ paragraph_index=paragraph_index,
409
+ table_index=table_index,
410
+ row=row,
411
+ col=col,
412
+ dry_run=dry_run,
413
+ )
414
+ return _with_document_state(result, path)
415
+
416
+
384
417
  def fill_form_field(
385
418
  filename: str,
386
419
  value: str,
@@ -589,6 +622,7 @@ apply_form_fill.__hwpx_input_schema_extra__ = { # type: ignore[attr-defined]
589
622
 
590
623
 
591
624
  __all__ = [
625
+ "add_form_field",
592
626
  "analyze_form_fill",
593
627
  "analyze_template_formfit",
594
628
  "apply_body_ops",
@@ -704,6 +704,31 @@ class HwpxOps:
704
704
  ) -> Dict[str, Any]:
705
705
  return self._services.form_fields.list_form_fields(path)
706
706
 
707
+ def add_form_field(
708
+ self,
709
+ path: str,
710
+ *,
711
+ name: str,
712
+ prompt: str = "",
713
+ memo: str = "",
714
+ paragraph_index: Optional[int] = None,
715
+ table_index: Optional[int] = None,
716
+ row: Optional[int] = None,
717
+ col: Optional[int] = None,
718
+ dry_run: bool = False,
719
+ ) -> Dict[str, Any]:
720
+ return self._services.form_fields.add_form_field(
721
+ path,
722
+ name=name,
723
+ prompt=prompt,
724
+ memo=memo,
725
+ paragraph_index=paragraph_index,
726
+ table_index=table_index,
727
+ row=row,
728
+ col=col,
729
+ dry_run=dry_run,
730
+ )
731
+
707
732
  def fill_form_field(
708
733
  self,
709
734
  path: str,
@@ -5,20 +5,20 @@
5
5
  "releaseState": {
6
6
  "status": "release-approved",
7
7
  "candidate": {
8
- "pythonHwpx": "5.0.1",
8
+ "pythonHwpx": "5.1.1",
9
9
  "canonicalDistribution": "python-hwpx-automation",
10
- "canonicalAutomation": "6.0.4",
10
+ "canonicalAutomation": "6.1.3",
11
11
  "compatibilityDistribution": "hwpx-mcp-server",
12
- "compatibility": "6.0.4",
13
- "plugin": "1.0.0",
14
- "contractHash": "0ce938371f0b55a6"
12
+ "compatibility": "6.1.3",
13
+ "plugin": "1.1.0",
14
+ "contractHash": "ac1a422376b5ac84"
15
15
  },
16
16
  "currentPublic": {
17
- "pythonHwpx": "4.2.0",
18
- "primaryDistribution": "hwpx-mcp-server",
19
- "primaryApplication": "5.1.0",
20
- "plugin": "0.8.0",
21
- "contractHash": "429cb6706323e762"
17
+ "pythonHwpx": "5.0.2",
18
+ "primaryDistribution": "python-hwpx-automation",
19
+ "primaryApplication": "6.0.4",
20
+ "plugin": "1.0.1",
21
+ "contractHash": "0ce938371f0b55a6"
22
22
  },
23
23
  "promotionGate": "Three states are mandatory: unreleased-candidate while auditing; release-approved only after separate owner approval and while currentPublic still names the previously observed coherent stack; released only in a follow-up commit after remote truth is observed for core, canonical automation, the compatibility distribution, the plugin GitHub release, the marketplace entry, and a real marketplace install. The automation tag workflow publishes only release-approved, leaves currentPublic unchanged, and hands an attached receipt to plugin publication."
24
24
  },
@@ -68,6 +68,67 @@ class FormFieldService:
68
68
  "fallback": "table-label" if not fields else None,
69
69
  }
70
70
 
71
+ def add_form_field(
72
+ self,
73
+ path: str,
74
+ *,
75
+ name: str,
76
+ prompt: str = "",
77
+ memo: str = "",
78
+ paragraph_index: int | None = None,
79
+ table_index: int | None = None,
80
+ row: int | None = None,
81
+ col: int | None = None,
82
+ dry_run: bool = False,
83
+ ) -> dict[str, Any]:
84
+ document, resolved = self._context._open_document(path)
85
+ cell_parts = (table_index, row, col)
86
+ use_cell = any(part is not None for part in cell_parts)
87
+ if use_cell and not all(part is not None for part in cell_parts):
88
+ raise self._context._new_error(
89
+ "FORM_FIELD_TARGET_INVALID",
90
+ "provide tableIndex, row, and col together for a cell target",
91
+ )
92
+ if use_cell and paragraph_index is not None:
93
+ raise self._context._new_error(
94
+ "FORM_FIELD_TARGET_INVALID",
95
+ "paragraphIndex cannot be combined with a cell target",
96
+ )
97
+ paragraph = None
98
+ if table_index is not None and row is not None and col is not None:
99
+ tables = self._context._iter_tables(document)
100
+ try:
101
+ table = tables[table_index]
102
+ except IndexError as exc:
103
+ raise self._context._new_error(
104
+ "TABLE_INDEX_OUT_OF_RANGE",
105
+ "tableIndex out of range",
106
+ details={"tableIndex": table_index},
107
+ ) from exc
108
+ try:
109
+ paragraph = table.cell(row, col).paragraphs[-1]
110
+ except (IndexError, ValueError) as exc:
111
+ raise self._context._new_error(
112
+ "TABLE_CELL_OPERATION_FAILED",
113
+ f"failed to resolve table cell for the form field: {exc}",
114
+ ) from exc
115
+ elif paragraph_index is not None:
116
+ try:
117
+ paragraph = document.paragraphs[paragraph_index]
118
+ except IndexError as exc:
119
+ raise self._context._new_error(
120
+ "PARAGRAPH_INDEX_OUT_OF_RANGE",
121
+ "paragraphIndex out of range",
122
+ details={"paragraphIndex": paragraph_index},
123
+ ) from exc
124
+ field = document.add_form_field(
125
+ name, prompt=prompt, memo=memo, paragraph=paragraph
126
+ )
127
+ result = {"ok": True, "filename": path, "field": field}
128
+ return self._transactions._with_transaction_verification(
129
+ result, document, resolved, dry_run=dry_run
130
+ )
131
+
71
132
  def fill_form_field(
72
133
  self,
73
134
  path: str,