python-hwpx-automation 7.0.3__tar.gz → 7.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_hwpx_automation-7.0.3/src/python_hwpx_automation.egg-info → python_hwpx_automation-7.1.0}/PKG-INFO +11 -12
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/README.md +9 -10
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/pyproject.toml +2 -2
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/quality_render.py +55 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/read_export.py +3 -1
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/identity.json +17 -10
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/cli.py +14 -1
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/document.py +30 -2
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/__init__.py +1 -1
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/wordbox.py +8 -8
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/quality.py +2 -2
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/_render_hwpx_mac.applescript +47 -35
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/diff.py +2 -2
- python_hwpx_automation-7.1.0/src/hwpx_automation/office/rendering/mac_session.py +87 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/oracle.py +33 -42
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/worker.py +56 -18
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/public-modules.json +6 -4
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/tool_contract.py +5 -4
- python_hwpx_automation-7.1.0/src/hwpx_automation/utils/read_budget.py +128 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/render_queue.py +17 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0/src/python_hwpx_automation.egg-info}/PKG-INFO +11 -12
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/python_hwpx_automation.egg-info/SOURCES.txt +2 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/python_hwpx_automation.egg-info/requires.txt +1 -1
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/LICENSE +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/MANIFEST.in +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/NOTICE +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/setup.cfg +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/__init__.pyi +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/__main__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/agent_document.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/api.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/blind_eval.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/capabilities.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/compat.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/configuration.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/content.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/context.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/diff.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/document.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/formatting.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/handles.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/locations.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/locator.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/plan.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/resources.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/search.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/transactions.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/core/txn.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/document_state.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/errors.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/execution_lock.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/fastmcp_adapter.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/form_fill.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/form_output_models.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/_shared.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/agent_document.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/authoring.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/content_edit.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/form_fill.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/layout_style.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/specialized.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/tracked_changes.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/handlers/workflow.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/hwp_converter.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/hwp_support.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/hwpx_ops.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/identity.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ingest_adapters.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/markdown_plan.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/mcp_cli.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/metadata/tools_meta.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/mixed_form.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/mutation_models.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/network_policy.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/_batch_verification.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/bundle.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/catalog.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/dump.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/mapping.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/model.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/native.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/blueprint/replay.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/catalog.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/commands.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/form_plan.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/model.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/path.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/query.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/agent/story.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/advanced_generators.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/builder/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/builder/core.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/builder/report.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/_support.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/composer.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/harvest.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/plan.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profile.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/body.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/heading.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/info_table.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/application_form/fragments/title.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/application_form/profile.json +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/application_form/template.hwpx +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/home_notice/fragments/body.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/home_notice/fragments/heading.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/home_notice/fragments/title.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/home_notice/profile.json +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/home_notice/template.hwpx +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/body.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/heading.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/info_table.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/official_notice/fragments/title.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/official_notice/profile.json +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/official_notice/template.hwpx +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/body.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/heading.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/info_table.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/report/fragments/title.xml +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/report/profile.json +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/profiles/report/template.hwpx +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/design/validator.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/presets/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/presets/proposal.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/report_parser.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/style_profile.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/authoring/template_analyzer.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/charting/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/compliance/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/compliance/official_lint.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/compliance/pii.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/document_ops/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/document_ops/comparison.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/document_ops/mail_merge.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/document_ops/redline.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/evalplan/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/evalplan/runtime.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/exam/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/exam/compose.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/exam/ir.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/exam/measure.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/exam/parser.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/exam/profile.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/classification.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fill_residue.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/apply.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/engine.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/measure.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/policy.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/report.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/fit/seal.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/guidance.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/split_run.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/form_fill/template_formfit.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/house_style/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/house_style/composition.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/house_style/data/bank.json +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/house_style/data/genres.json +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/house_style/gianmun.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/house_style/org_chart.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/quality/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/quality/page_guard.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/_hancom_open_rate.ps1 +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/_refresh_hwpx_mac.applescript +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/_render_hwpx.ps1 +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/block_splits.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/detectors.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/fixture_corpus.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/page_qa.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/qa_contracts.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/rendering/qa_metrics.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/utilities/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/office/utilities/table_compute.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/_border_fill.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/composition.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/content_layout.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/context.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/form_fields.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/media.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/memo_style.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/package_validation.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/planning.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/preview_export.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/read_query.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/save_policy.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/tables.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/ops_services/transactions.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/preview_output_models.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/py.typed +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/quality.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/quality_generation.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/resources.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/runtime.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/runtime_services.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/server.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/storage.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/tool_bindings.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/upstream.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/utils/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/utils/helpers.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/visual_qa.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/__init__.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/adapters.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/dispatcher.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/models.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/policy.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/render_contracts.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/render_metrics.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/render_security.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/render_transport.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/rendering.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/service.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/state_machine.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workflow/store.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/workspace.py +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/python_hwpx_automation.egg-info/dependency_links.txt +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/python_hwpx_automation.egg-info/entry_points.txt +0 -0
- {python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/python_hwpx_automation.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-hwpx-automation
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.1.0
|
|
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
|
|
@@ -20,7 +20,7 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
License-File: NOTICE
|
|
23
|
-
Requires-Dist: python-hwpx<7,>=6.
|
|
23
|
+
Requires-Dist: python-hwpx<7,>=6.4.0
|
|
24
24
|
Requires-Dist: pydantic<3,>=2.11
|
|
25
25
|
Requires-Dist: cryptography>=42.0
|
|
26
26
|
Requires-Dist: anyio>=4.0
|
|
@@ -74,15 +74,12 @@ Dynamic: license-file
|
|
|
74
74
|
|
|
75
75
|
<!-- release-state: release-approved -->
|
|
76
76
|
> [!NOTE]
|
|
77
|
-
>
|
|
78
|
-
> hwpx
|
|
79
|
-
>
|
|
80
|
-
>
|
|
81
|
-
>
|
|
82
|
-
>
|
|
83
|
-
> 공개 좌표는 원격 진실(core·automation PyPI와 plugin GitHub
|
|
84
|
-
> Release·marketplace·실제 marketplace 설치) 관찰 후에만
|
|
85
|
-
> 승격됩니다 — [릴리스 runbook](docs/release-runbook.md)
|
|
77
|
+
> 이 소스는 발행 승인된(release-approved) 7.1.0 후보입니다. 원격 발행과 실제 설치 관찰 전까지 공개 좌표는 유지합니다.
|
|
78
|
+
> 후보: `python-hwpx 6.4.0 → python-hwpx-automation 7.1.0 → hwpx-plugin 2.2.0` (`ba0211fc854a0a97`).
|
|
79
|
+
> 공개 트레인: `python-hwpx 6.3.0 → python-hwpx-automation 7.0.4 → hwpx-plugin 2.1.0` (`8c278ebd5becba08`).
|
|
80
|
+
> 공개 좌표는 core·automation PyPI와 plugin GitHub
|
|
81
|
+
> Release·marketplace·실제 marketplace 설치 관찰 후에만 승격합니다.
|
|
82
|
+
> [릴리스 runbook](docs/release-runbook.md)
|
|
86
83
|
|
|
87
84
|
[python-hwpx](https://github.com/airmang/python-hwpx) 엔진 위에서 문서 저작·
|
|
88
85
|
양식 채움·시험지 조판·안전한 에이전트 워크플로를 제공하는 응용 계층입니다.
|
|
@@ -136,7 +133,7 @@ Gemini CLI는 `~/.gemini/settings.json`, Cursor·Windsurf는 각 에디터의 MC
|
|
|
136
133
|
"command": "uvx",
|
|
137
134
|
"args": [
|
|
138
135
|
"--from",
|
|
139
|
-
"python-hwpx-automation[mcp]==7.0.
|
|
136
|
+
"python-hwpx-automation[mcp]==7.0.4",
|
|
140
137
|
"hwpx-automation-mcp"
|
|
141
138
|
],
|
|
142
139
|
"env": {
|
|
@@ -243,3 +240,5 @@ python scripts/run_conformance.py run \
|
|
|
243
240
|
## License · Maintainer
|
|
244
241
|
|
|
245
242
|
Apache-2.0 ([LICENSE](LICENSE) · [NOTICE](NOTICE)) — **Kohkyuhyun** [@airmang](https://github.com/airmang) · [kokyuhyun@hotmail.com](mailto:kokyuhyun@hotmail.com)
|
|
243
|
+
|
|
244
|
+
기존 문서 수정은 [조회·대상 확정·보존 저장·검증 안내](docs/existing-edit-navigation.md)를 먼저 확인하세요. 새 문서는 document-plan, 에이전트 연결은 선택 MCP와 호스트 플러그인을 사용합니다.
|
|
@@ -14,15 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
<!-- release-state: release-approved -->
|
|
16
16
|
> [!NOTE]
|
|
17
|
-
>
|
|
18
|
-
> hwpx
|
|
19
|
-
>
|
|
20
|
-
>
|
|
21
|
-
>
|
|
22
|
-
>
|
|
23
|
-
> 공개 좌표는 원격 진실(core·automation PyPI와 plugin GitHub
|
|
24
|
-
> Release·marketplace·실제 marketplace 설치) 관찰 후에만
|
|
25
|
-
> 승격됩니다 — [릴리스 runbook](docs/release-runbook.md)
|
|
17
|
+
> 이 소스는 발행 승인된(release-approved) 7.1.0 후보입니다. 원격 발행과 실제 설치 관찰 전까지 공개 좌표는 유지합니다.
|
|
18
|
+
> 후보: `python-hwpx 6.4.0 → python-hwpx-automation 7.1.0 → hwpx-plugin 2.2.0` (`ba0211fc854a0a97`).
|
|
19
|
+
> 공개 트레인: `python-hwpx 6.3.0 → python-hwpx-automation 7.0.4 → hwpx-plugin 2.1.0` (`8c278ebd5becba08`).
|
|
20
|
+
> 공개 좌표는 core·automation PyPI와 plugin GitHub
|
|
21
|
+
> Release·marketplace·실제 marketplace 설치 관찰 후에만 승격합니다.
|
|
22
|
+
> [릴리스 runbook](docs/release-runbook.md)
|
|
26
23
|
|
|
27
24
|
[python-hwpx](https://github.com/airmang/python-hwpx) 엔진 위에서 문서 저작·
|
|
28
25
|
양식 채움·시험지 조판·안전한 에이전트 워크플로를 제공하는 응용 계층입니다.
|
|
@@ -76,7 +73,7 @@ Gemini CLI는 `~/.gemini/settings.json`, Cursor·Windsurf는 각 에디터의 MC
|
|
|
76
73
|
"command": "uvx",
|
|
77
74
|
"args": [
|
|
78
75
|
"--from",
|
|
79
|
-
"python-hwpx-automation[mcp]==7.0.
|
|
76
|
+
"python-hwpx-automation[mcp]==7.0.4",
|
|
80
77
|
"hwpx-automation-mcp"
|
|
81
78
|
],
|
|
82
79
|
"env": {
|
|
@@ -183,3 +180,5 @@ python scripts/run_conformance.py run \
|
|
|
183
180
|
## License · Maintainer
|
|
184
181
|
|
|
185
182
|
Apache-2.0 ([LICENSE](LICENSE) · [NOTICE](NOTICE)) — **Kohkyuhyun** [@airmang](https://github.com/airmang) · [kokyuhyun@hotmail.com](mailto:kokyuhyun@hotmail.com)
|
|
183
|
+
|
|
184
|
+
기존 문서 수정은 [조회·대상 확정·보존 저장·검증 안내](docs/existing-edit-navigation.md)를 먼저 확인하세요. 새 문서는 document-plan, 에이전트 연결은 선택 MCP와 호스트 플러그인을 사용합니다.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-hwpx-automation"
|
|
7
|
-
version = "7.0
|
|
7
|
+
version = "7.1.0"
|
|
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" }]
|
|
@@ -31,7 +31,7 @@ dependencies = [
|
|
|
31
31
|
# breaking an already-published automation line. WP-F (engine surface 6.0):
|
|
32
32
|
# this line adapted to the new namespace surface (design §9 WP-F) — the dev0
|
|
33
33
|
# pre-release qualifier tracks core's own not-yet-tagged 6.0 identity.
|
|
34
|
-
"python-hwpx>=6.
|
|
34
|
+
"python-hwpx>=6.4.0,<7", # HWPX object model, OXML/OPC, format-native primitives
|
|
35
35
|
|
|
36
36
|
"pydantic>=2.11,<3",
|
|
37
37
|
"cryptography>=42.0",
|
|
@@ -272,6 +272,60 @@ def describe_capabilities(domain: str | None = None) -> dict:
|
|
|
272
272
|
return report
|
|
273
273
|
|
|
274
274
|
|
|
275
|
+
_STACK_UPDATE_STATE_SCHEMA = "hwpx.stack-update-state.v1"
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _stack_update_block() -> dict[str, Any]:
|
|
279
|
+
"""Launcher-managed runtime update state (hwpx-plugins Feature 066).
|
|
280
|
+
|
|
281
|
+
The bundled launcher writes update-state.json and passes its path as
|
|
282
|
+
HWPX_STACK_UPDATE_STATE. Without it the runtime is not launcher-managed
|
|
283
|
+
(pip install, editable checkout, plain uvx) and the block says so; it
|
|
284
|
+
never guesses.
|
|
285
|
+
"""
|
|
286
|
+
path = os.environ.get("HWPX_STACK_UPDATE_STATE")
|
|
287
|
+
if not path:
|
|
288
|
+
return {"available": False, "reason": "NOT_MANAGED"}
|
|
289
|
+
try:
|
|
290
|
+
with open(path, encoding="utf-8") as handle:
|
|
291
|
+
state = json.load(handle)
|
|
292
|
+
except FileNotFoundError:
|
|
293
|
+
return {"available": False, "reason": "STATE_MISSING", "path": path}
|
|
294
|
+
except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc:
|
|
295
|
+
return {"available": False, "reason": "STATE_UNREADABLE", "path": path, "detail": str(exc)}
|
|
296
|
+
if not isinstance(state, dict) or state.get("schemaVersion") != _STACK_UPDATE_STATE_SCHEMA:
|
|
297
|
+
return {"available": False, "reason": "STATE_SCHEMA_UNKNOWN", "path": path}
|
|
298
|
+
runtime = state.get("runtime")
|
|
299
|
+
if not isinstance(runtime, dict):
|
|
300
|
+
return {"available": False, "reason": "STATE_INVALID", "path": path}
|
|
301
|
+
installed = runtime.get("installed")
|
|
302
|
+
if (
|
|
303
|
+
not isinstance(installed, dict)
|
|
304
|
+
or set(installed) != {"python-hwpx", "python-hwpx-automation"}
|
|
305
|
+
or not all(isinstance(value, str) and value for value in installed.values())
|
|
306
|
+
):
|
|
307
|
+
return {"available": False, "reason": "STATE_INVALID", "path": path}
|
|
308
|
+
running = {
|
|
309
|
+
"python-hwpx": _package_version("python-hwpx"),
|
|
310
|
+
"python-hwpx-automation": _package_version("python-hwpx-automation"),
|
|
311
|
+
}
|
|
312
|
+
runtime = {
|
|
313
|
+
**runtime,
|
|
314
|
+
"running": running,
|
|
315
|
+
"restartRequired": runtime["installed"] != running,
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
"available": True,
|
|
319
|
+
"path": path,
|
|
320
|
+
"checkedAt": state.get("checkedAt"),
|
|
321
|
+
"autoUpdate": state.get("autoUpdate"),
|
|
322
|
+
"channel": state.get("channel"),
|
|
323
|
+
"runtime": runtime,
|
|
324
|
+
"pluginBundle": state.get("pluginBundle"),
|
|
325
|
+
"lastError": state.get("lastError"),
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
275
329
|
def mcp_server_health() -> dict:
|
|
276
330
|
"""MCP 서버 transport와 timeout/keepalive 점검 정보를 반환합니다."""
|
|
277
331
|
transport = env_value("TRANSPORT", "stdio")
|
|
@@ -386,6 +440,7 @@ def mcp_server_health() -> dict:
|
|
|
386
440
|
),
|
|
387
441
|
},
|
|
388
442
|
"capability": _capability_block(skew_detected, surface_details),
|
|
443
|
+
"stackUpdate": _stack_update_block(),
|
|
389
444
|
"unitPolicy": {
|
|
390
445
|
"status": "audited",
|
|
391
446
|
"fontSize": "points",
|
|
@@ -38,6 +38,7 @@ from ..upstream import (
|
|
|
38
38
|
open_document,
|
|
39
39
|
)
|
|
40
40
|
from ..utils.helpers import default_max_chars, resolve_path, truncate_response
|
|
41
|
+
from ..utils.read_budget import bound_document_summary
|
|
41
42
|
from ._shared import _with_document_state
|
|
42
43
|
|
|
43
44
|
_OUTPUT_MODES = {"full", "chunks"}
|
|
@@ -920,7 +921,8 @@ def get_document_map(
|
|
|
920
921
|
"hwpx_extract_json",
|
|
921
922
|
],
|
|
922
923
|
}
|
|
923
|
-
|
|
924
|
+
result = _with_document_state(result, path)
|
|
925
|
+
return bound_document_summary(result) if summary_mode else result
|
|
924
926
|
|
|
925
927
|
|
|
926
928
|
def hwpx_to_markdown(
|
{python_hwpx_automation-7.0.3 → python_hwpx_automation-7.1.0}/src/hwpx_automation/identity.json
RENAMED
|
@@ -5,22 +5,29 @@
|
|
|
5
5
|
"releaseState": {
|
|
6
6
|
"status": "release-approved",
|
|
7
7
|
"candidate": {
|
|
8
|
-
"pythonHwpx": "6.
|
|
8
|
+
"pythonHwpx": "6.4.0",
|
|
9
9
|
"canonicalDistribution": "python-hwpx-automation",
|
|
10
|
-
"canonicalAutomation": "7.0
|
|
10
|
+
"canonicalAutomation": "7.1.0",
|
|
11
11
|
"compatibilityDistribution": "hwpx-mcp-server",
|
|
12
|
-
"compatibility": "7.0
|
|
13
|
-
"plugin": "2.0
|
|
14
|
-
"contractHash": "
|
|
12
|
+
"compatibility": "7.1.0",
|
|
13
|
+
"plugin": "2.2.0",
|
|
14
|
+
"contractHash": "ba0211fc854a0a97"
|
|
15
15
|
},
|
|
16
16
|
"currentPublic": {
|
|
17
|
-
"pythonHwpx": "6.
|
|
17
|
+
"pythonHwpx": "6.3.0",
|
|
18
18
|
"primaryDistribution": "python-hwpx-automation",
|
|
19
|
-
"primaryApplication": "7.0.
|
|
20
|
-
"plugin": "2.0
|
|
21
|
-
"contractHash": "
|
|
19
|
+
"primaryApplication": "7.0.4",
|
|
20
|
+
"plugin": "2.1.0",
|
|
21
|
+
"contractHash": "8c278ebd5becba08"
|
|
22
22
|
},
|
|
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."
|
|
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
|
+
"previousPublic": {
|
|
25
|
+
"pythonHwpx": "6.3.0",
|
|
26
|
+
"primaryDistribution": "python-hwpx-automation",
|
|
27
|
+
"primaryApplication": "7.0.4",
|
|
28
|
+
"plugin": "2.1.0",
|
|
29
|
+
"contractHash": "8c278ebd5becba08"
|
|
30
|
+
}
|
|
24
31
|
},
|
|
25
32
|
"releaseFloors": {
|
|
26
33
|
"description": "Frozen historical coordinates. Unlike releaseState these do not advance train by train; they pin the pre-6.0 legacy compatibility cap that every core 5 resolution must be observed against. They live here so the release path has no version literal that is not declared data.",
|
|
@@ -23,6 +23,10 @@ from .blueprint import (
|
|
|
23
23
|
)
|
|
24
24
|
from .commands import apply_document_commands
|
|
25
25
|
from .document import HwpxAgentDocument
|
|
26
|
+
from .form_plan import (
|
|
27
|
+
MIXED_FORM_PLAN_SCHEMA, MIXED_FORM_COMPILED_PLAN_SCHEMA,
|
|
28
|
+
apply_mixed_form_fill, apply_mixed_form_plan,
|
|
29
|
+
)
|
|
26
30
|
from .model import (
|
|
27
31
|
AGENT_BATCH_SCHEMA,
|
|
28
32
|
AgentBatchResult,
|
|
@@ -536,6 +540,15 @@ def _run_replay(args: argparse.Namespace, *, stdin: TextIO, stdout: TextIO) -> i
|
|
|
536
540
|
return _exit_code(result.error)
|
|
537
541
|
|
|
538
542
|
|
|
543
|
+
def _apply_batch_request(request: Mapping[str, Any], store: dict[str, Any]) -> AgentBatchResult:
|
|
544
|
+
schema = request.get("schemaVersion")
|
|
545
|
+
if schema == MIXED_FORM_PLAN_SCHEMA:
|
|
546
|
+
return apply_mixed_form_fill(request, idempotency_store=store)
|
|
547
|
+
if schema == MIXED_FORM_COMPILED_PLAN_SCHEMA:
|
|
548
|
+
return apply_mixed_form_plan(request, idempotency_store=store)
|
|
549
|
+
return apply_document_commands(request, idempotency_store=store)
|
|
550
|
+
|
|
551
|
+
|
|
539
552
|
def _run_mutation(
|
|
540
553
|
args: argparse.Namespace,
|
|
541
554
|
*,
|
|
@@ -550,7 +563,7 @@ def _run_mutation(
|
|
|
550
563
|
exit_code = EXIT_OK
|
|
551
564
|
results: list[AgentBatchResult] = []
|
|
552
565
|
for request in requests:
|
|
553
|
-
result =
|
|
566
|
+
result = _apply_batch_request(request, store)
|
|
554
567
|
results.append(result)
|
|
555
568
|
exit_code = max(exit_code, _exit_code(result.error))
|
|
556
569
|
if args.output_format == "human":
|
|
@@ -21,7 +21,7 @@ from .model import (
|
|
|
21
21
|
AgentNode,
|
|
22
22
|
NODE_PROPERTY_CATALOG_V1,
|
|
23
23
|
)
|
|
24
|
-
from .path import SemanticPath, canonicalize_path, identified_segment, indexed_segment
|
|
24
|
+
from .path import SemanticPath, canonicalize_path, identified_segment, indexed_segment, parse_path
|
|
25
25
|
from .query import QueryRecord as _QueryRecord
|
|
26
26
|
from .query import QueryResult, evaluate_selector, parse_selector
|
|
27
27
|
from .story import (
|
|
@@ -804,9 +804,37 @@ class HwpxAgentDocument:
|
|
|
804
804
|
f"childLimit must be 1..{MAX_CHILDREN_PER_NODE}",
|
|
805
805
|
target="childLimit",
|
|
806
806
|
)
|
|
807
|
-
|
|
807
|
+
try:
|
|
808
|
+
record = self.resolve_record(path, expected_revision=expected_revision)
|
|
809
|
+
except AgentContractError as exc:
|
|
810
|
+
if exc.code != "not_found":
|
|
811
|
+
raise
|
|
812
|
+
record = self._resolve_indexed_read_path(path, expected_revision)
|
|
808
813
|
return self._public_node(record, depth=depth, child_limit=child_limit)
|
|
809
814
|
|
|
815
|
+
def _resolve_indexed_read_path(self, path: str, revision: str | None) -> NodeRecord:
|
|
816
|
+
"""Navigate omitted children; return a canonical path for subsequent edits.
|
|
817
|
+
|
|
818
|
+
Only get() calls this helper. Commands continue to require the exact
|
|
819
|
+
canonical path, so a navigation alias never silently retargets a write.
|
|
820
|
+
"""
|
|
821
|
+
record = self._records["/"]
|
|
822
|
+
for segment in parse_path(path).segments:
|
|
823
|
+
direct = record.path.rstrip("/") + "/" + segment.canonical()
|
|
824
|
+
if direct in record.child_paths:
|
|
825
|
+
record = self.resolve_record(direct, expected_revision=revision)
|
|
826
|
+
continue
|
|
827
|
+
children = [self._records[p] for p in record.child_paths
|
|
828
|
+
if self._records[p].kind == segment.kind]
|
|
829
|
+
if segment.index is None or segment.index > len(children):
|
|
830
|
+
raise AgentContractError("not_found", "indexed read target not found", target=path)
|
|
831
|
+
if revision is None:
|
|
832
|
+
raise AgentContractError(
|
|
833
|
+
"volatile_target", "indexed navigation requires the current revision", target=path
|
|
834
|
+
)
|
|
835
|
+
record = self.resolve_record(children[segment.index - 1].path, expected_revision=revision)
|
|
836
|
+
return record
|
|
837
|
+
|
|
810
838
|
def query(
|
|
811
839
|
self,
|
|
812
840
|
selector: str,
|
|
@@ -1292,7 +1292,7 @@ def inspect_document_authoring_quality(
|
|
|
1292
1292
|
_rendered = _mac.render_pdf(str(_hwpx), str(_pdf))
|
|
1293
1293
|
if _rendered and Path(_rendered).exists():
|
|
1294
1294
|
try:
|
|
1295
|
-
import
|
|
1295
|
+
import pymupdf as _fitz
|
|
1296
1296
|
|
|
1297
1297
|
_doc = _fitz.open(_rendered)
|
|
1298
1298
|
_has_text = any(
|
|
@@ -185,7 +185,7 @@ def fitz_available() -> bool:
|
|
|
185
185
|
"""True when PyMuPDF (``fitz``) can be imported (the extraction backend)."""
|
|
186
186
|
|
|
187
187
|
try: # pragma: no cover - trivial import probe
|
|
188
|
-
import fitz # noqa: F401
|
|
188
|
+
import pymupdf as fitz # noqa: F401
|
|
189
189
|
except Exception:
|
|
190
190
|
return False
|
|
191
191
|
return True
|
|
@@ -205,7 +205,7 @@ def extract_word_boxes(pdf_path: str, *, page: int | None = None) -> list[WordBo
|
|
|
205
205
|
|
|
206
206
|
if not fitz_available():
|
|
207
207
|
raise OracleUnavailable("PyMuPDF (fitz) is not installed")
|
|
208
|
-
import fitz
|
|
208
|
+
import pymupdf as fitz
|
|
209
209
|
|
|
210
210
|
boxes: list[WordBox] = []
|
|
211
211
|
try:
|
|
@@ -255,7 +255,7 @@ def extract_glyph_boxes(pdf_path: str, *, page: int | None = None) -> list[WordB
|
|
|
255
255
|
|
|
256
256
|
if not fitz_available():
|
|
257
257
|
raise OracleUnavailable("PyMuPDF (fitz) is not installed")
|
|
258
|
-
import fitz
|
|
258
|
+
import pymupdf as fitz
|
|
259
259
|
|
|
260
260
|
boxes: list[WordBox] = []
|
|
261
261
|
try:
|
|
@@ -709,7 +709,7 @@ def render_glyph_boxes(
|
|
|
709
709
|
if not pdf or not os.path.exists(pdf) or os.path.getsize(pdf) == 0:
|
|
710
710
|
raise OracleUnavailable("Hancom render produced no PDF")
|
|
711
711
|
boxes = extract_glyph_boxes(pdf, page=page)
|
|
712
|
-
import fitz
|
|
712
|
+
import pymupdf as fitz
|
|
713
713
|
|
|
714
714
|
with fitz.open(pdf) as doc:
|
|
715
715
|
if len(doc) == 0: # a 0-page render is a failed render, not a clean pass
|
|
@@ -742,7 +742,7 @@ def extract_cell_clips(pdf_path: str, *, page: int | None = None) -> list[Rect]:
|
|
|
742
742
|
|
|
743
743
|
if not fitz_available():
|
|
744
744
|
raise OracleUnavailable("PyMuPDF (fitz) is not installed")
|
|
745
|
-
import fitz
|
|
745
|
+
import pymupdf as fitz
|
|
746
746
|
|
|
747
747
|
clips: list[Rect] = []
|
|
748
748
|
try:
|
|
@@ -785,7 +785,7 @@ def extract_image_boxes(pdf_path: str, *, page: int | None = None) -> list[Rect]
|
|
|
785
785
|
|
|
786
786
|
if not fitz_available():
|
|
787
787
|
raise OracleUnavailable("PyMuPDF (fitz) is not installed")
|
|
788
|
-
import fitz
|
|
788
|
+
import pymupdf as fitz
|
|
789
789
|
|
|
790
790
|
boxes: list[Rect] = []
|
|
791
791
|
try:
|
|
@@ -843,7 +843,7 @@ def render_form_geometry(
|
|
|
843
843
|
raise OracleUnavailable("Hancom render produced no PDF")
|
|
844
844
|
glyphs = extract_glyph_boxes(rendered, page=page)
|
|
845
845
|
clips = extract_cell_clips(rendered, page=page)
|
|
846
|
-
import fitz
|
|
846
|
+
import pymupdf as fitz
|
|
847
847
|
|
|
848
848
|
with fitz.open(rendered) as doc:
|
|
849
849
|
if len(doc) == 0:
|
|
@@ -957,7 +957,7 @@ def extract_layout_signature(pdf_path: str) -> LayoutSignature:
|
|
|
957
957
|
|
|
958
958
|
if not fitz_available():
|
|
959
959
|
raise OracleUnavailable("PyMuPDF (fitz) is not installed")
|
|
960
|
-
import fitz
|
|
960
|
+
import pymupdf as fitz
|
|
961
961
|
|
|
962
962
|
try:
|
|
963
963
|
doc = fitz.open(pdf_path)
|
|
@@ -180,7 +180,7 @@ def detect_overflow_crossings(
|
|
|
180
180
|
PyMuPDF; raises ``RuntimeError`` if unavailable (caller degrades to unverified).
|
|
181
181
|
"""
|
|
182
182
|
try:
|
|
183
|
-
import fitz
|
|
183
|
+
import pymupdf as fitz
|
|
184
184
|
except Exception as exc: # pragma: no cover - env probe
|
|
185
185
|
raise RuntimeError(f"PyMuPDF unavailable: {exc}") from exc
|
|
186
186
|
|
|
@@ -266,7 +266,7 @@ def score_render(
|
|
|
266
266
|
[f"render imaging deps unavailable: {exc}"],
|
|
267
267
|
)
|
|
268
268
|
|
|
269
|
-
import fitz # already importable if we got here
|
|
269
|
+
import pymupdf as fitz # already importable if we got here
|
|
270
270
|
|
|
271
271
|
doc = fitz.open(pdf)
|
|
272
272
|
pages = doc.page_count
|
|
@@ -30,6 +30,10 @@ property closeDocPrefix : "문서 닫기"
|
|
|
30
30
|
|
|
31
31
|
on run argv
|
|
32
32
|
if (count of argv) < 2 then return "ERR: usage: <input.hwpx> <out.pdf> [timeoutSecs]"
|
|
33
|
+
if item 1 of argv is "--close-owned" then
|
|
34
|
+
closeOwnedDocument(item 2 of argv)
|
|
35
|
+
return "CLEANUP"
|
|
36
|
+
end if
|
|
33
37
|
set inputPath to item 1 of argv
|
|
34
38
|
set outPdf to item 2 of argv
|
|
35
39
|
set timeoutSecs to 90
|
|
@@ -41,6 +45,18 @@ on run argv
|
|
|
41
45
|
|
|
42
46
|
set inputBase to do shell script "basename " & quoted form of inputPath
|
|
43
47
|
|
|
48
|
+
if listContains(windowNames(), inputBase) then return "ERR: staged document already open"
|
|
49
|
+
if listContains(windowNames(), pdfDialogTitle) then return "ERR: existing PDF dialog"
|
|
50
|
+
-- Do not drive menus while another document owns a modal sheet.
|
|
51
|
+
tell application "System Events"
|
|
52
|
+
if exists process procName then
|
|
53
|
+
tell process procName
|
|
54
|
+
repeat with w in windows
|
|
55
|
+
if (count of sheets of w) > 0 then return "ERR: existing modal sheet"
|
|
56
|
+
end repeat
|
|
57
|
+
end tell
|
|
58
|
+
end if
|
|
59
|
+
end tell
|
|
44
60
|
try
|
|
45
61
|
-- 1) Open the staged input. LaunchServices focuses Hancom (launching it
|
|
46
62
|
-- if needed) and opens the document.
|
|
@@ -61,7 +77,7 @@ on run argv
|
|
|
61
77
|
|
|
62
78
|
-- 4) Wait for the export dialog.
|
|
63
79
|
if not (waitForWindowNamed(pdfDialogTitle, 30)) then
|
|
64
|
-
|
|
80
|
+
error "PDF save dialog did not appear"
|
|
65
81
|
end if
|
|
66
82
|
delay 1.0
|
|
67
83
|
|
|
@@ -94,19 +110,14 @@ on run argv
|
|
|
94
110
|
-- 8) Always close the document so the next render starts from a clean
|
|
95
111
|
-- session, even if the wait above was noisy. Discard any save-changes
|
|
96
112
|
-- prompt (we only exported; the doc content is unmodified).
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
dismissCloseSheetIfPresent()
|
|
100
|
-
end try
|
|
113
|
+
set closed to closeOwnedDocument(inputBase)
|
|
114
|
+
if not closed then return "ERR: owned document cleanup incomplete"
|
|
101
115
|
|
|
102
116
|
if not wrote then return "ERR: PDF not written to " & outPdf
|
|
103
117
|
return "OK"
|
|
104
118
|
on error errMsg number errNum
|
|
105
119
|
-- Best-effort cleanup so a mid-flow error doesn't leak an open document.
|
|
106
|
-
|
|
107
|
-
clickFileMenuItemByPrefix(closeDocPrefix)
|
|
108
|
-
dismissCloseSheetIfPresent()
|
|
109
|
-
end try
|
|
120
|
+
closeOwnedDocument(inputBase)
|
|
110
121
|
return "ERR: " & errMsg & " (" & errNum & ")"
|
|
111
122
|
end try
|
|
112
123
|
end run
|
|
@@ -221,29 +232,30 @@ on dismissOverwriteSheetIfPresent()
|
|
|
221
232
|
return false
|
|
222
233
|
end dismissOverwriteSheetIfPresent
|
|
223
234
|
|
|
224
|
-
--
|
|
225
|
-
--
|
|
226
|
-
on
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
end
|
|
235
|
+
-- Never discard a sheet belonging to any other document. If ownership cannot
|
|
236
|
+
-- be proved, leave the GUI for the user and report failure rather than kill it.
|
|
237
|
+
on closeOwnedDocument(winName)
|
|
238
|
+
if not listContains(windowNames(), winName) then return false
|
|
239
|
+
if listContains(windowNames(), pdfDialogTitle) then return false
|
|
240
|
+
try
|
|
241
|
+
raiseWindowNamed(winName)
|
|
242
|
+
tell application "System Events" to tell process procName
|
|
243
|
+
if name of front window is not winName then return false
|
|
244
|
+
end tell
|
|
245
|
+
clickFileMenuItemByPrefix(closeDocPrefix)
|
|
246
|
+
tell application "System Events" to tell process procName
|
|
247
|
+
if exists (first window whose name is winName) then
|
|
248
|
+
set owned to (first window whose name is winName)
|
|
249
|
+
if (count of sheets of owned) > 0 then
|
|
250
|
+
repeat with b in buttons of sheet 1 of owned
|
|
251
|
+
set bn to name of b as string
|
|
252
|
+
if bn contains "안 함" or bn contains "안함" then click b
|
|
253
|
+
end repeat
|
|
254
|
+
end if
|
|
255
|
+
end if
|
|
256
|
+
end tell
|
|
257
|
+
return waitForWindowGone(winName, 2)
|
|
258
|
+
on error
|
|
259
|
+
return false
|
|
260
|
+
end try
|
|
261
|
+
end closeOwnedDocument
|
|
@@ -27,7 +27,7 @@ _TALL_BAND_REL = 1.0
|
|
|
27
27
|
|
|
28
28
|
def pymupdf_available() -> bool:
|
|
29
29
|
try: # pragma: no cover - trivial import probe
|
|
30
|
-
import fitz # noqa: F401
|
|
30
|
+
import pymupdf as fitz # noqa: F401
|
|
31
31
|
except Exception:
|
|
32
32
|
return False
|
|
33
33
|
return True
|
|
@@ -36,7 +36,7 @@ def pymupdf_available() -> bool:
|
|
|
36
36
|
def render_pdf_to_images(pdf_path: str | Path, dpi: int = 150) -> list["Image.Image"]:
|
|
37
37
|
"""Rasterize every page of ``pdf_path`` to a list of RGB ``PIL.Image``."""
|
|
38
38
|
|
|
39
|
-
import fitz # pymupdf
|
|
39
|
+
import pymupdf as fitz # pymupdf
|
|
40
40
|
from PIL import Image
|
|
41
41
|
|
|
42
42
|
pages: list[Image.Image] = []
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Owned, cancellable Mac GUI adapter for the existing serialized worker."""
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import plistlib
|
|
7
|
+
import subprocess
|
|
8
|
+
import tempfile
|
|
9
|
+
import threading
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from .oracle import MacHancomOracle
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _OwnedMacOracle(MacHancomOracle):
|
|
16
|
+
def __init__(self, *, timeout: float) -> None:
|
|
17
|
+
super().__init__(timeout=timeout, budget_seconds=timeout)
|
|
18
|
+
self.guard = threading.Lock()
|
|
19
|
+
self.process: subprocess.Popen[str] | None = None
|
|
20
|
+
self.cancelled = threading.Event()
|
|
21
|
+
|
|
22
|
+
def _run_render_script(self, cmd: list[str], timeout: float) -> subprocess.CompletedProcess[str]:
|
|
23
|
+
with self.guard:
|
|
24
|
+
if self.cancelled.is_set():
|
|
25
|
+
raise OSError("render cancelled before launch")
|
|
26
|
+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
|
27
|
+
self.process = process
|
|
28
|
+
try:
|
|
29
|
+
try:
|
|
30
|
+
stdout, stderr = process.communicate(timeout=timeout)
|
|
31
|
+
except subprocess.TimeoutExpired:
|
|
32
|
+
process.kill()
|
|
33
|
+
process.communicate()
|
|
34
|
+
raise
|
|
35
|
+
if self.cancelled.is_set():
|
|
36
|
+
raise OSError("render cancelled")
|
|
37
|
+
return subprocess.CompletedProcess(cmd, process.returncode, stdout, stderr)
|
|
38
|
+
finally:
|
|
39
|
+
with self.guard:
|
|
40
|
+
self.process = None
|
|
41
|
+
|
|
42
|
+
def abort(self) -> None:
|
|
43
|
+
self.cancelled.set()
|
|
44
|
+
with self.guard:
|
|
45
|
+
if self.process is not None and self.process.poll() is None:
|
|
46
|
+
self.process.kill() # our osascript only; never the user's app
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class MacHancomSession:
|
|
50
|
+
real_hancom = True
|
|
51
|
+
backend = "mac-gui-worker"
|
|
52
|
+
|
|
53
|
+
def __init__(self, *, timeout_seconds: float = 120) -> None:
|
|
54
|
+
self.oracle = _OwnedMacOracle(timeout=timeout_seconds)
|
|
55
|
+
app = self.oracle._app_path()
|
|
56
|
+
if app is None or not self.oracle.available():
|
|
57
|
+
raise RuntimeError("MAC_HANCOM_UNAVAILABLE")
|
|
58
|
+
with (Path(app) / "Contents/Info.plist").open("rb") as handle:
|
|
59
|
+
info = plistlib.load(handle)
|
|
60
|
+
version, build = info.get("CFBundleShortVersionString"), info.get("CFBundleVersion")
|
|
61
|
+
if not version or not build:
|
|
62
|
+
raise RuntimeError("MAC_HANCOM_BUILD_UNKNOWN")
|
|
63
|
+
self.hancom_build = f"{version} ({build})"
|
|
64
|
+
|
|
65
|
+
def render_pdf(self, source: Path, target: Path) -> Path | None:
|
|
66
|
+
from hwpx_automation.workflow.render_queue import inspect_hwpx
|
|
67
|
+
inspect_hwpx(source.read_bytes(), filename=source.name, principal_id="local-worker")
|
|
68
|
+
# The Mac desktop is shared even across worker roots/processes. flock
|
|
69
|
+
# lives until the rendering/owned cleanup exits, including watchdogs.
|
|
70
|
+
import fcntl
|
|
71
|
+
lock = Path(tempfile.gettempdir()) / f"hwpx-hancom-gui-{os.getuid()}.lock"
|
|
72
|
+
with lock.open("a") as handle:
|
|
73
|
+
try:
|
|
74
|
+
fcntl.flock(handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
75
|
+
except BlockingIOError:
|
|
76
|
+
raise RuntimeError("MAC_GUI_BUSY") from None
|
|
77
|
+
try:
|
|
78
|
+
result = self.oracle.render_pdf(str(source), str(target))
|
|
79
|
+
return Path(result) if result else None
|
|
80
|
+
finally:
|
|
81
|
+
fcntl.flock(handle, fcntl.LOCK_UN)
|
|
82
|
+
|
|
83
|
+
def abort(self) -> None:
|
|
84
|
+
self.oracle.abort()
|
|
85
|
+
|
|
86
|
+
def close(self) -> None:
|
|
87
|
+
self.abort()
|