contextweave 0.3.1__tar.gz → 2.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (558) hide show
  1. {contextweave-0.3.1 → contextweave-2.7.0}/.github/workflows/release.yml +62 -1
  2. {contextweave-0.3.1 → contextweave-2.7.0}/PKG-INFO +1 -1
  3. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/__init__.py +4 -0
  4. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/translate_and_export_task_worker.py +3 -1
  5. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/document.py +13 -0
  6. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/work.py +1 -0
  7. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/runtime.py +5 -7
  8. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/_export_support.py +40 -4
  9. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/app_setup.py +7 -1
  10. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/document.py +64 -39
  11. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/projects.py +14 -5
  12. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/work.py +9 -1
  13. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/cli/config_file.py +8 -0
  14. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/cli/main.py +2 -0
  15. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/config.py +7 -0
  16. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/context_manager.py +14 -1
  17. contextweave-2.7.0/context_aware_translation/core/galgame_document_handler.py +119 -0
  18. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub.py +1 -1
  19. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/galgame.py +49 -145
  20. contextweave-0.3.1/context_aware_translation/ui/constants.py → contextweave-2.7.0/context_aware_translation/languages.py +15 -21
  21. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/client.py +16 -1
  22. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/glossary_translator.py +9 -1
  23. contextweave-2.7.0/context_aware_translation/llm/language_pair_prompts/__init__.py +63 -0
  24. contextweave-2.7.0/context_aware_translation/llm/language_pair_prompts/japanese_to_simplified_chinese.py +16 -0
  25. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/translator.py +43 -6
  26. contextweave-2.7.0/context_aware_translation/stdio.py +38 -0
  27. contextweave-2.7.0/context_aware_translation/ui/constants.py +26 -0
  28. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/app_setup_view.py +2 -2
  29. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/document_translation_view.py +44 -3
  30. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/document_workspace_view.py +15 -5
  31. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/work_view.py +0 -16
  32. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/workflow_profile_editor.py +2 -2
  33. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/main.py +2 -0
  34. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/document/DocumentShellChrome.qml +1 -1
  35. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/resources/styles.qss +27 -4
  36. contextweave-2.7.0/context_aware_translation/ui/widgets/hybrid_controls.py +341 -0
  37. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/export_ops.py +15 -0
  38. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/translate_and_export_support.py +3 -2
  39. {contextweave-0.3.1 → contextweave-2.7.0}/docs/examples/contextweave-cli.yaml +2 -2
  40. {contextweave-0.3.1 → contextweave-2.7.0}/pyproject.toml +1 -1
  41. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/fakes.py +24 -1
  42. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_composition.py +23 -9
  43. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_document_service.py +60 -1
  44. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_document_translation_service.py +71 -0
  45. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_export_services.py +112 -0
  46. {contextweave-0.3.1 → contextweave-2.7.0}/tests/cli/test_cli.py +19 -2
  47. {contextweave-0.3.1 → contextweave-2.7.0}/tests/config/test_endpoint_profiles.py +31 -15
  48. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test_context_manager.py +8 -8
  49. contextweave-2.7.0/tests/core/test_galgame_document_handler.py +139 -0
  50. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test_translation_context_manager_strategy_api.py +3 -3
  51. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_galgame.py +138 -43
  52. {contextweave-0.3.1 → contextweave-2.7.0}/tests/integration/test_business_logic.py +1 -1
  53. contextweave-2.7.0/tests/llm/test_language_pair_prompts.py +90 -0
  54. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_llm_client.py +36 -0
  55. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_translator.py +34 -0
  56. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_book_manager.py +19 -19
  57. contextweave-2.7.0/tests/test_languages.py +34 -0
  58. contextweave-2.7.0/tests/test_stdio.py +25 -0
  59. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_app_setup_view.py +6 -5
  60. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_translation_view.py +55 -0
  61. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_library_view.py +7 -8
  62. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_work_view.py +11 -16
  63. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_workflow_profile_editor.py +1 -0
  64. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_import_export.py +107 -2
  65. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_session.py +1 -1
  66. contextweave-0.3.1/context_aware_translation/core/galgame_document_handler.py +0 -65
  67. contextweave-0.3.1/context_aware_translation/ui/widgets/hybrid_controls.py +0 -153
  68. contextweave-0.3.1/tests/core/test_galgame_document_handler.py +0 -57
  69. {contextweave-0.3.1 → contextweave-2.7.0}/.gitignore +0 -0
  70. {contextweave-0.3.1 → contextweave-2.7.0}/AGENTS.md +0 -0
  71. {contextweave-0.3.1 → contextweave-2.7.0}/LICENSE +0 -0
  72. {contextweave-0.3.1 → contextweave-2.7.0}/Makefile +0 -0
  73. {contextweave-0.3.1 → contextweave-2.7.0}/README.md +0 -0
  74. {contextweave-0.3.1 → contextweave-2.7.0}/README_ZH.md +0 -0
  75. {contextweave-0.3.1 → contextweave-2.7.0}/cat-ui.spec +0 -0
  76. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/AGENTS.md +0 -0
  77. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/__init__.py +0 -0
  78. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/files/__init__.py +0 -0
  79. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/files/glossary_io.py +0 -0
  80. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/__init__.py +0 -0
  81. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/application_event_bridge.py +0 -0
  82. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/task_engine.py +0 -0
  83. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/__init__.py +0 -0
  84. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/base_worker.py +0 -0
  85. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/batch_task_overlap_guard.py +0 -0
  86. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/batch_translation_task_worker.py +0 -0
  87. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/chunk_retranslation_task_worker.py +0 -0
  88. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/export_worker.py +0 -0
  89. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/glossary_export_task_worker.py +0 -0
  90. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/glossary_extraction_task_worker.py +0 -0
  91. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/glossary_review_task_worker.py +0 -0
  92. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/glossary_translation_task_worker.py +0 -0
  93. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/image_reembedding_task_worker.py +0 -0
  94. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/import_worker.py +0 -0
  95. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/ocr_task_worker.py +0 -0
  96. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/operation_tracker.py +0 -0
  97. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/translation_manga_task_worker.py +0 -0
  98. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/adapters/qt/workers/translation_text_task_worker.py +0 -0
  99. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/app_identity.py +0 -0
  100. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/__init__.py +0 -0
  101. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/composition.py +0 -0
  102. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/__init__.py +0 -0
  103. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/app_setup.py +0 -0
  104. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/common.py +0 -0
  105. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/project_setup.py +0 -0
  106. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/projects.py +0 -0
  107. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/queue.py +0 -0
  108. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/contracts/terms.py +0 -0
  109. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/errors.py +0 -0
  110. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/events.py +0 -0
  111. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/__init__.py +0 -0
  112. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/project_setup.py +0 -0
  113. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/queue.py +0 -0
  114. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/application/services/terms.py +0 -0
  115. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/cli/__init__.py +0 -0
  116. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/cli/galgame_skill.py +0 -0
  117. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/cli/output.py +0 -0
  118. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/cli/runtime.py +0 -0
  119. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/cli/wait.py +0 -0
  120. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/AGENTS.md +0 -0
  121. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/__init__.py +0 -0
  122. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/cancellation.py +0 -0
  123. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/context_extractor.py +0 -0
  124. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/manga_document_handler.py +0 -0
  125. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/models.py +0 -0
  126. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/progress.py +0 -0
  127. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/term_memory.py +0 -0
  128. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/term_memory_builder.py +0 -0
  129. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/core/translation_strategies.py +0 -0
  130. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/AGENTS.md +0 -0
  131. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/__init__.py +0 -0
  132. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/base.py +0 -0
  133. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/content/AGENTS.md +0 -0
  134. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/content/__init__.py +0 -0
  135. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/content/ocr_content.py +0 -0
  136. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/content/ocr_items.py +0 -0
  137. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_container.py +0 -0
  138. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/AGENTS.md +0 -0
  139. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/__init__.py +0 -0
  140. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/container_model.py +0 -0
  141. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/container_patch.py +0 -0
  142. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/container_reader.py +0 -0
  143. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/container_shared.py +0 -0
  144. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/container_writer.py +0 -0
  145. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/inline_markers.py +0 -0
  146. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/nav_ops.py +0 -0
  147. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/slot_lines.py +0 -0
  148. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_support/xml_utils.py +0 -0
  149. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/epub_xhtml_utils.py +0 -0
  150. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/manga.py +0 -0
  151. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/manga_alignment.py +0 -0
  152. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/manga_reembed_planner.py +0 -0
  153. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/pdf.py +0 -0
  154. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/scanned_book.py +0 -0
  155. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/subtitle.py +0 -0
  156. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/documents/text.py +0 -0
  157. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/AGENTS.md +0 -0
  158. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/__init__.py +0 -0
  159. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/batch_jobs/AGENTS.md +0 -0
  160. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/batch_jobs/__init__.py +0 -0
  161. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/batch_jobs/base.py +0 -0
  162. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/batch_jobs/gemini_gateway.py +0 -0
  163. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/epub_ocr.py +0 -0
  164. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/extractor.py +0 -0
  165. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/image_backend_base.py +0 -0
  166. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/image_backends/AGENTS.md +0 -0
  167. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/image_backends/__init__.py +0 -0
  168. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/image_backends/gemini_backend.py +0 -0
  169. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/image_backends/openai_backend.py +0 -0
  170. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/image_backends/qwen_backend.py +0 -0
  171. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/image_generator.py +0 -0
  172. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/language_detector.py +0 -0
  173. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/manga_ocr.py +0 -0
  174. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/manga_translator.py +0 -0
  175. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/ocr.py +0 -0
  176. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/reviewer.py +0 -0
  177. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/session_trace.py +0 -0
  178. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/summarizor.py +0 -0
  179. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/token_tracker.py +0 -0
  180. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/llm/translation_strategies.py +0 -0
  181. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/hk2s.json +0 -0
  182. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/jp2s.json +0 -0
  183. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/s2hk.json +0 -0
  184. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/s2t.json +0 -0
  185. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/s2tw.json +0 -0
  186. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/s2twp.json +0 -0
  187. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/t2hk.json +0 -0
  188. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/t2s.json +0 -0
  189. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/t2tw.json +0 -0
  190. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/tw2s.json +0 -0
  191. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/config/tw2sp.json +0 -0
  192. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/HKVariants.txt +0 -0
  193. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/HKVariantsPhrases.txt +0 -0
  194. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/HKVariantsRev.txt +0 -0
  195. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/HKVariantsRevPhrases.txt +0 -0
  196. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/JPVariants.txt +0 -0
  197. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/JPVariantsRev.txt +0 -0
  198. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/STCharacters.txt +0 -0
  199. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/STPhrases.txt +0 -0
  200. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/TSCharacters.txt +0 -0
  201. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/TSPhrases.txt +0 -0
  202. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/TWPhrases.txt +0 -0
  203. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/TWPhrasesRev.txt +0 -0
  204. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/TWVariants.txt +0 -0
  205. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/TWVariantsRev.txt +0 -0
  206. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/opencc/dictionary/TWVariantsRevPhrases.txt +0 -0
  207. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/tokenizers/deepseek-v3/special_tokens_map.json +0 -0
  208. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/tokenizers/deepseek-v3/tokenizer.json +0 -0
  209. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/resources/tokenizers/deepseek-v3/tokenizer_config.json +0 -0
  210. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/AGENTS.md +0 -0
  211. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/__init__.py +0 -0
  212. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/library/__init__.py +0 -0
  213. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/library/book_manager.py +0 -0
  214. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/models/__init__.py +0 -0
  215. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/models/book.py +0 -0
  216. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/models/config_profile.py +0 -0
  217. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/models/endpoint_profile.py +0 -0
  218. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/repositories/__init__.py +0 -0
  219. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/repositories/document_repository.py +0 -0
  220. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/repositories/llm_batch_store.py +0 -0
  221. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/repositories/task_store.py +0 -0
  222. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/repositories/term_repository.py +0 -0
  223. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/repositories/translation_batch_task_store.py +0 -0
  224. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/schema/__init__.py +0 -0
  225. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/schema/book_db.py +0 -0
  226. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/schema/registry_db.py +0 -0
  227. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/storage/sqlite_locking.py +0 -0
  228. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/AGENTS.md +0 -0
  229. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/__init__.py +0 -0
  230. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/chrome_sizing.py +0 -0
  231. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/app_settings_pane.py +0 -0
  232. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/document_images_view.py +0 -0
  233. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/document_ocr_tab.py +0 -0
  234. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/library_view.py +0 -0
  235. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/project_settings_pane.py +0 -0
  236. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/queue_drawer_view.py +0 -0
  237. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/terms_table_widget.py +0 -0
  238. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/features/terms_view.py +0 -0
  239. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/i18n.py +0 -0
  240. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/json_utils.py +0 -0
  241. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/main_window.py +0 -0
  242. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/BootstrapProbe.qml +0 -0
  243. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/app/AppShellChrome.qml +0 -0
  244. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/dialogs/app_settings/AppSettingsDialogChrome.qml +0 -0
  245. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/dialogs/app_settings/AppSettingsPane.qml +0 -0
  246. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/dialogs/project_settings/ProjectSettingsDialogChrome.qml +0 -0
  247. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/dialogs/project_settings/ProjectSettingsPane.qml +0 -0
  248. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/document/export/DocumentExportPaneChrome.qml +0 -0
  249. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/document/images/DocumentImagesPaneChrome.qml +0 -0
  250. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/document/ocr/DocumentOCRPaneChrome.qml +0 -0
  251. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/document/translation/DocumentTranslationPaneChrome.qml +0 -0
  252. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/project/ProjectShellChrome.qml +0 -0
  253. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/project/terms/TermsPaneChrome.qml +0 -0
  254. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/project/work_home/WorkHomeChrome.qml +0 -0
  255. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml/queue/QueueShellChrome.qml +0 -0
  256. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/qml_resources.py +0 -0
  257. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/resources/__init__.py +0 -0
  258. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/__init__.py +0 -0
  259. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/app_settings_dialog_host.py +0 -0
  260. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/app_shell_host.py +0 -0
  261. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/document_shell_host.py +0 -0
  262. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/hybrid.py +0 -0
  263. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/project_settings_dialog_host.py +0 -0
  264. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/project_shell_host.py +0 -0
  265. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/shell_hosts/queue_shell_host.py +0 -0
  266. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/sleep_inhibitor.py +0 -0
  267. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/startup.py +0 -0
  268. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/tips.py +0 -0
  269. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/translations/zh_CN.qm +0 -0
  270. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/translations/zh_CN.ts +0 -0
  271. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/__init__.py +0 -0
  272. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/app_settings_dialog.py +0 -0
  273. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/app_settings_pane.py +0 -0
  274. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/app_shell.py +0 -0
  275. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/base.py +0 -0
  276. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/document_export_pane.py +0 -0
  277. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/document_images_pane.py +0 -0
  278. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/document_ocr_pane.py +0 -0
  279. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/document_shell.py +0 -0
  280. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/document_translation_pane.py +0 -0
  281. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/project_settings_dialog.py +0 -0
  282. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/project_settings_pane.py +0 -0
  283. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/project_shell.py +0 -0
  284. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/queue_shell.py +0 -0
  285. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/router.py +0 -0
  286. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/terms_pane.py +0 -0
  287. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/viewmodels/work_home.py +0 -0
  288. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/widgets/AGENTS.md +0 -0
  289. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/widgets/image_viewer.py +0 -0
  290. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/widgets/progress_widget.py +0 -0
  291. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/widgets/table_support.py +0 -0
  292. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/ui/window_controllers.py +0 -0
  293. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/AGENTS.md +0 -0
  294. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/__init__.py +0 -0
  295. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/chunking.py +0 -0
  296. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/cjk_normalize.py +0 -0
  297. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/compression_marker.py +0 -0
  298. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/file_utils.py +0 -0
  299. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/hard_wrap.py +0 -0
  300. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/hashing.py +0 -0
  301. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/image_utils.py +0 -0
  302. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/llm_json_cleaner.py +0 -0
  303. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/markdown_escape.py +0 -0
  304. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/pandoc_export.py +0 -0
  305. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/semantic_chunker.py +0 -0
  306. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/string_similarity.py +0 -0
  307. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/utils/symbol_check.py +0 -0
  308. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/AGENTS.md +0 -0
  309. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/__init__.py +0 -0
  310. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/bootstrap.py +0 -0
  311. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/image_fetcher.py +0 -0
  312. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/__init__.py +0 -0
  313. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/bootstrap_ops.py +0 -0
  314. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/glossary_ops.py +0 -0
  315. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/import_ops.py +0 -0
  316. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/import_support.py +0 -0
  317. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/ocr_ops.py +0 -0
  318. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/ops/translation_ops.py +0 -0
  319. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/runtime.py +0 -0
  320. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/session.py +0 -0
  321. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/task_runtime.py +0 -0
  322. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/AGENTS.md +0 -0
  323. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/__init__.py +0 -0
  324. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/claims.py +0 -0
  325. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/engine_core.py +0 -0
  326. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/exceptions.py +0 -0
  327. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/execution/AGENTS.md +0 -0
  328. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/execution/__init__.py +0 -0
  329. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/execution/batch_translation_executor.py +0 -0
  330. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/execution/batch_translation_ops.py +0 -0
  331. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/glossary_preflight.py +0 -0
  332. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/AGENTS.md +0 -0
  333. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/__init__.py +0 -0
  334. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/base.py +0 -0
  335. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/batch_translation.py +0 -0
  336. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/chunk_retranslation.py +0 -0
  337. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/glossary_export.py +0 -0
  338. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/glossary_extraction.py +0 -0
  339. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/glossary_review.py +0 -0
  340. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/glossary_translation.py +0 -0
  341. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/image_reembedding.py +0 -0
  342. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/ocr.py +0 -0
  343. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/translate_and_export.py +0 -0
  344. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/translation_manga.py +0 -0
  345. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/handlers/translation_text.py +0 -0
  346. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/models.py +0 -0
  347. {contextweave-0.3.1 → contextweave-2.7.0}/context_aware_translation/workflow/tasks/worker_deps.py +0 -0
  348. {contextweave-0.3.1 → contextweave-2.7.0}/demo/The Count of Monte Cristo.epub +0 -0
  349. {contextweave-0.3.1 → contextweave-2.7.0}/demo//345/237/272/347/235/243/345/261/261/344/274/257/347/210/265.epub" +0 -0
  350. {contextweave-0.3.1 → contextweave-2.7.0}/docs/.nojekyll +0 -0
  351. {contextweave-0.3.1 → contextweave-2.7.0}/docs/index.html +0 -0
  352. {contextweave-0.3.1 → contextweave-2.7.0}/docs/project-terms-manual-entry-ux.md +0 -0
  353. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN/API/351/205/215/347/275/256.png" +0 -0
  354. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN/latest_new_project_dialog.png +0 -0
  355. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN/latest_project_work_overview.png +0 -0
  356. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN/latest_projects_overview.png +0 -0
  357. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN/latest_setup_wizard_provider_selection.png +0 -0
  358. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN/latest_setup_wizard_workflow_profile_review.png +0 -0
  359. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN/latest_terms_overview.png +0 -0
  360. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//345/257/274/345/205/245.png" +0 -0
  361. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//345/257/274/345/207/272.png" +0 -0
  362. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//346/226/260/351/241/271/347/233/256.png" +0 -0
  363. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//346/234/257/350/257/255.png" +0 -0
  364. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//347/277/273/350/257/221.png" +0 -0
  365. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//350/256/276/347/275/256.png" +0 -0
  366. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//350/256/276/347/275/256/345/220/221/345/257/274.png" +0 -0
  367. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/CN//350/256/276/347/275/256/347/273/223/346/235/237.png" +0 -0
  368. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/APISetup.png +0 -0
  369. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/Export.png +0 -0
  370. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/Import.png +0 -0
  371. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/InitialSetup.png +0 -0
  372. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/Language.png +0 -0
  373. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/NewProject.png +0 -0
  374. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/Terms.png +0 -0
  375. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/Translate.png +0 -0
  376. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/TranslateAndExport.png +0 -0
  377. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/Wizard.png +0 -0
  378. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/latest_new_project_dialog.png +0 -0
  379. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/latest_project_work_overview.png +0 -0
  380. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/latest_projects_overview.png +0 -0
  381. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/latest_setup_wizard_provider_selection.png +0 -0
  382. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/latest_setup_wizard_workflow_profile_review.png +0 -0
  383. {contextweave-0.3.1 → contextweave-2.7.0}/docs/screenshots/EN/latest_terms_overview.png +0 -0
  384. {contextweave-0.3.1 → contextweave-2.7.0}/docs/styles.css +0 -0
  385. {contextweave-0.3.1 → contextweave-2.7.0}/installer/AGENTS.md +0 -0
  386. {contextweave-0.3.1 → contextweave-2.7.0}/installer/macos/AGENTS.md +0 -0
  387. {contextweave-0.3.1 → contextweave-2.7.0}/installer/macos/entitlements.plist +0 -0
  388. {contextweave-0.3.1 → contextweave-2.7.0}/installer/windows/AGENTS.md +0 -0
  389. {contextweave-0.3.1 → contextweave-2.7.0}/scripts/AGENTS.md +0 -0
  390. {contextweave-0.3.1 → contextweave-2.7.0}/scripts/build_ui.py +0 -0
  391. {contextweave-0.3.1 → contextweave-2.7.0}/scripts/generate_readme_screenshots.py +0 -0
  392. {contextweave-0.3.1 → contextweave-2.7.0}/scripts/run_ui_tests.py +0 -0
  393. {contextweave-0.3.1 → contextweave-2.7.0}/tests/AGENTS.md +0 -0
  394. {contextweave-0.3.1 → contextweave-2.7.0}/tests/adapters/AGENTS.md +0 -0
  395. {contextweave-0.3.1 → contextweave-2.7.0}/tests/adapters/files/test_glossary_io.py +0 -0
  396. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_contracts.py +0 -0
  397. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_events.py +0 -0
  398. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_queue_service.py +0 -0
  399. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_terms_service.py +0 -0
  400. {contextweave-0.3.1 → contextweave-2.7.0}/tests/application/test_ui_harness_pattern.py +0 -0
  401. {contextweave-0.3.1 → contextweave-2.7.0}/tests/architecture/test_migrated_ui_boundaries.py +0 -0
  402. {contextweave-0.3.1 → contextweave-2.7.0}/tests/architecture/test_packaging_hidden_imports.py +0 -0
  403. {contextweave-0.3.1 → contextweave-2.7.0}/tests/architecture/test_qml_ui_boundaries.py +0 -0
  404. {contextweave-0.3.1 → contextweave-2.7.0}/tests/config/AGENTS.md +0 -0
  405. {contextweave-0.3.1 → contextweave-2.7.0}/tests/config/__init__.py +0 -0
  406. {contextweave-0.3.1 → contextweave-2.7.0}/tests/conftest.py +0 -0
  407. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/AGENTS.md +0 -0
  408. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/__init__.py +0 -0
  409. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/expected_batching_output.json +0 -0
  410. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test-terms.json +0 -0
  411. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test_context_extractor.py +0 -0
  412. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test_manga_document_handler.py +0 -0
  413. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test_models.py +0 -0
  414. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test_noise_filtering_pipeline.py +0 -0
  415. {contextweave-0.3.1 → contextweave-2.7.0}/tests/core/test_term_memory_builder.py +0 -0
  416. {contextweave-0.3.1 → contextweave-2.7.0}/tests/data/test_chunk.txt +0 -0
  417. {contextweave-0.3.1 → contextweave-2.7.0}/tests/data/test_chunk2.txt +0 -0
  418. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/AGENTS.md +0 -0
  419. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/__init__.py +0 -0
  420. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/content/AGENTS.md +0 -0
  421. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/content/test_ocr_content.py +0 -0
  422. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/content/test_ocr_items.py +0 -0
  423. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_base.py +0 -0
  424. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_epub.py +0 -0
  425. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_epub_container.py +0 -0
  426. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_epub_inline_markers.py +0 -0
  427. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_epub_xhtml_utils.py +0 -0
  428. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_manga.py +0 -0
  429. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_manga_alignment.py +0 -0
  430. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_ocr_image_embedded_text.py +0 -0
  431. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_pdf.py +0 -0
  432. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_scanned_book.py +0 -0
  433. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_subtitle.py +0 -0
  434. {contextweave-0.3.1 → contextweave-2.7.0}/tests/documents/test_text.py +0 -0
  435. {contextweave-0.3.1 → contextweave-2.7.0}/tests/integration/AGENTS.md +0 -0
  436. {contextweave-0.3.1 → contextweave-2.7.0}/tests/integration/__init__.py +0 -0
  437. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/AGENTS.md +0 -0
  438. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/__init__.py +0 -0
  439. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_extractor.py +0 -0
  440. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_extractor_unit.py +0 -0
  441. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_gemini_backend.py +0 -0
  442. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_gemini_batch_gateway.py +0 -0
  443. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_glossary_translator.py +0 -0
  444. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_image_generator.py +0 -0
  445. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_image_token_usage.py +0 -0
  446. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_language_detector.py +0 -0
  447. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_manga_translator.py +0 -0
  448. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_ocr.py +0 -0
  449. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_reviewer.py +0 -0
  450. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_session_trace.py +0 -0
  451. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_summarizor.py +0 -0
  452. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_token_tracker.py +0 -0
  453. {contextweave-0.3.1 → contextweave-2.7.0}/tests/llm/test_token_usage_extraction.py +0 -0
  454. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/AGENTS.md +0 -0
  455. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/__init__.py +0 -0
  456. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_book_db.py +0 -0
  457. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_document_repository.py +0 -0
  458. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_document_tables.py +0 -0
  459. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_llm_batch_store.py +0 -0
  460. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_task_store.py +0 -0
  461. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_term_repository.py +0 -0
  462. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_token_tracking.py +0 -0
  463. {contextweave-0.3.1 → contextweave-2.7.0}/tests/storage/test_translation_batch_task_store.py +0 -0
  464. {contextweave-0.3.1 → contextweave-2.7.0}/tests/test_logging_handlers.py +0 -0
  465. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/AGENTS.md +0 -0
  466. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/__init__.py +0 -0
  467. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/conftest.py +0 -0
  468. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/tasks/test_task_engine.py +0 -0
  469. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_app_settings_dialog_host.py +0 -0
  470. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_app_settings_dialog_viewmodel.py +0 -0
  471. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_app_settings_pane.py +0 -0
  472. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_app_settings_pane_viewmodel.py +0 -0
  473. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_app_shell_host.py +0 -0
  474. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_app_shell_viewmodel.py +0 -0
  475. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_export_pane_viewmodel.py +0 -0
  476. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_images_pane_viewmodel.py +0 -0
  477. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_images_view.py +0 -0
  478. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_ocr_tab.py +0 -0
  479. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_shell_host.py +0 -0
  480. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_shell_viewmodel.py +0 -0
  481. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_translation_pane_viewmodel.py +0 -0
  482. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_document_workspace_view.py +0 -0
  483. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_i18n_progress_messages.py +0 -0
  484. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_image_viewer.py +0 -0
  485. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_main.py +0 -0
  486. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_main_window_shell.py +0 -0
  487. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_progress_widget.py +0 -0
  488. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_project_settings_dialog_host.py +0 -0
  489. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_project_settings_dialog_viewmodel.py +0 -0
  490. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_project_settings_pane.py +0 -0
  491. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_project_settings_pane_viewmodel.py +0 -0
  492. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_project_shell_host.py +0 -0
  493. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_project_shell_viewmodel.py +0 -0
  494. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_qml_bootstrap.py +0 -0
  495. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_qml_viewmodel_harness.py +0 -0
  496. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_queue_drawer_view.py +0 -0
  497. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_queue_shell_host.py +0 -0
  498. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_queue_shell_viewmodel.py +0 -0
  499. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_shell_host_infrastructure.py +0 -0
  500. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_sleep_inhibitor.py +0 -0
  501. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_terms_pane_viewmodel.py +0 -0
  502. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_terms_view.py +0 -0
  503. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_ui_clickthrough_smoke.py +0 -0
  504. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_viewmodel_base.py +0 -0
  505. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/test_worker_cancellation_reporting.py +0 -0
  506. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_batch_task_overlap_guard.py +0 -0
  507. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_chunk_retranslation_task_worker.py +0 -0
  508. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_config_snapshot_workers.py +0 -0
  509. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_glossary_export_task_worker.py +0 -0
  510. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_glossary_review_task_worker.py +0 -0
  511. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_ocr_task_worker.py +0 -0
  512. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_operation_tracker.py +0 -0
  513. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_translate_and_export_task_worker.py +0 -0
  514. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_translation_manga_task_worker.py +0 -0
  515. {contextweave-0.3.1 → contextweave-2.7.0}/tests/ui/workers/test_translation_text_task_worker.py +0 -0
  516. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/AGENTS.md +0 -0
  517. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/__init__.py +0 -0
  518. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_chunking.py +0 -0
  519. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_cjk_normalize.py +0 -0
  520. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_file_utils.py +0 -0
  521. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_hard_wrap.py +0 -0
  522. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_hashing.py +0 -0
  523. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_llm_json_cleaner.py +0 -0
  524. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_markdown_escape.py +0 -0
  525. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_semantic_chunker.py +0 -0
  526. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_string_similarity.py +0 -0
  527. {contextweave-0.3.1 → contextweave-2.7.0}/tests/utils/test_symbol_check.py +0 -0
  528. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/AGENTS.md +0 -0
  529. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/__init__.py +0 -0
  530. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/AGENTS.md +0 -0
  531. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/__init__.py +0 -0
  532. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/execution/AGENTS.md +0 -0
  533. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/execution/__init__.py +0 -0
  534. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/execution/test_batch_translation_executor.py +0 -0
  535. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/AGENTS.md +0 -0
  536. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/__init__.py +0 -0
  537. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_batch_translation_handler.py +0 -0
  538. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_chunk_retranslation_handler.py +0 -0
  539. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_glossary_export_handler.py +0 -0
  540. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_glossary_extraction_handler.py +0 -0
  541. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_glossary_review_handler.py +0 -0
  542. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_glossary_translation_handler.py +0 -0
  543. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_image_reembedding_handler.py +0 -0
  544. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_ocr_handler.py +0 -0
  545. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_translate_and_export_handler.py +0 -0
  546. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_translation_manga_handler.py +0 -0
  547. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/handlers/test_translation_text_handler.py +0 -0
  548. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/test_claims.py +0 -0
  549. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/tasks/test_engine_core.py +0 -0
  550. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_glossary_ops_scoping.py +0 -0
  551. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_multi_document.py +0 -0
  552. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_ocr_required_for_translation.py +0 -0
  553. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_run_ocr.py +0 -0
  554. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_service_bootstrap_lock.py +0 -0
  555. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_service_cancellation_semantics.py +0 -0
  556. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_translator_image_fetcher.py +0 -0
  557. {contextweave-0.3.1 → contextweave-2.7.0}/tests/workflow/test_translator_import_path.py +0 -0
  558. {contextweave-0.3.1 → contextweave-2.7.0}/uv.lock +0 -0
@@ -373,8 +373,69 @@ jobs:
373
373
  if-no-files-found: error
374
374
  retention-days: 5
375
375
 
376
+ build-python-package:
377
+ name: Build Python package
378
+ runs-on: ubuntu-latest
379
+ if: startsWith(github.ref, 'refs/tags/v')
380
+ permissions:
381
+ contents: read
382
+
383
+ steps:
384
+ - name: Checkout
385
+ uses: actions/checkout@v4
386
+
387
+ - name: Set up Python
388
+ uses: actions/setup-python@v5
389
+ with:
390
+ python-version: ${{ env.PYTHON_VERSION }}
391
+
392
+ - name: Install uv
393
+ uses: astral-sh/setup-uv@v4
394
+
395
+ - name: Set package version from tag
396
+ shell: bash
397
+ run: |
398
+ VERSION="${GITHUB_REF_NAME#v}"
399
+ uv version "$VERSION" --frozen
400
+ echo "Building contextweave $(uv version --short)"
401
+
402
+ - name: Build package distributions
403
+ run: uv build --clear
404
+
405
+ - name: Validate package distributions
406
+ run: uvx --from twine twine check dist/*
407
+
408
+ - name: Upload Python package distributions
409
+ uses: actions/upload-artifact@v4
410
+ with:
411
+ name: python-package-distributions
412
+ path: dist/*
413
+ if-no-files-found: error
414
+ retention-days: 5
415
+
416
+ publish-pypi:
417
+ name: Publish Python package to PyPI
418
+ needs: [build, build-python-package]
419
+ runs-on: ubuntu-latest
420
+ if: startsWith(github.ref, 'refs/tags/v')
421
+ environment:
422
+ name: pypi
423
+ url: https://pypi.org/p/contextweave
424
+ permissions:
425
+ id-token: write
426
+
427
+ steps:
428
+ - name: Download Python package distributions
429
+ uses: actions/download-artifact@v4
430
+ with:
431
+ name: python-package-distributions
432
+ path: dist
433
+
434
+ - name: Publish package distributions to PyPI
435
+ uses: pypa/gh-action-pypi-publish@release/v1
436
+
376
437
  release:
377
- needs: build
438
+ needs: [build, build-python-package]
378
439
  runs-on: ubuntu-latest
379
440
  if: startsWith(github.ref, 'refs/tags/v')
380
441
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contextweave
3
- Version: 0.3.1
3
+ Version: 2.7.0
4
4
  Summary: ContextWeave: context-aware document translation with glossary management
5
5
  Project-URL: Homepage, https://github.com/bot-32142/ContextWeave
6
6
  Project-URL: Documentation, https://bot-32142.github.io/ContextWeave/
@@ -9,6 +9,8 @@ import sys
9
9
  from pathlib import Path
10
10
  from typing import TYPE_CHECKING
11
11
 
12
+ from context_aware_translation.stdio import configure_standard_streams
13
+
12
14
  if TYPE_CHECKING:
13
15
  from context_aware_translation.config import Config
14
16
 
@@ -53,6 +55,8 @@ def configure_logging(config: "Config") -> None:
53
55
  """
54
56
  global _logging_configured
55
57
 
58
+ configure_standard_streams()
59
+
56
60
  # Skip configuration if we're in a test environment (pytest will handle it)
57
61
  is_test_env = (
58
62
  "pytest" in sys.modules
@@ -191,7 +191,9 @@ class TranslateAndExportTaskWorker(BaseWorker):
191
191
  progress_callback=self._on_progress,
192
192
  )
193
193
 
194
- preserve_structure = bool(self._options.get("preserve_structure", False))
194
+ export_documents = bootstrap_ops.load_documents(workflow, [self._document_id])
195
+ requires_preserve_structure = any(document.document_type == "galgame" for document in export_documents)
196
+ preserve_structure = requires_preserve_structure or bool(self._options.get("preserve_structure", False))
195
197
  if preserve_structure:
196
198
  await export_ops.export_preserve_structure(
197
199
  workflow,
@@ -132,6 +132,17 @@ class SaveTranslationRequest(ContractModel):
132
132
  translated_text: str
133
133
 
134
134
 
135
+ class TranslationUnitUpdate(ContractModel):
136
+ unit_id: str
137
+ translated_text: str
138
+
139
+
140
+ class SaveTranslationsRequest(ContractModel):
141
+ project_id: str
142
+ document_id: int
143
+ updates: list[TranslationUnitUpdate] = Field(default_factory=list)
144
+
145
+
135
146
  class RetranslateRequest(ContractModel):
136
147
  project_id: str
137
148
  document_id: int
@@ -192,6 +203,7 @@ class DocumentExportState(ContractModel):
192
203
  default_output_path: str | None = None
193
204
  blocker: BlockerInfo | None = None
194
205
  supports_preserve_structure: bool = False
206
+ requires_preserve_structure: bool = False
195
207
  supports_original_image_export: bool = False
196
208
  supports_epub_layout_conversion: bool = False
197
209
  incomplete_translation_message: str | None = None
@@ -216,6 +228,7 @@ class TranslateAndExportState(ContractModel):
216
228
  default_output_path: str | None = None
217
229
  blocker: BlockerInfo | None = None
218
230
  supports_preserve_structure: bool = False
231
+ requires_preserve_structure: bool = False
219
232
  supports_original_image_export: bool = False
220
233
  supports_epub_layout_conversion: bool = False
221
234
  batch_available: bool = False
@@ -94,6 +94,7 @@ class ExportDialogState(ContractModel):
94
94
  default_output_path: str | None = None
95
95
  blocker: BlockerInfo | None = None
96
96
  supports_preserve_structure: bool = False
97
+ requires_preserve_structure: bool = False
97
98
  supports_original_image_export: bool = False
98
99
  supports_epub_layout_conversion: bool = False
99
100
  incomplete_translation_message: str | None = None
@@ -53,6 +53,10 @@ from context_aware_translation.application.events import (
53
53
  WorkboardInvalidatedEvent,
54
54
  )
55
55
  from context_aware_translation.config import Config, infer_async_batch_provider
56
+ from context_aware_translation.languages import (
57
+ display_target_language_name,
58
+ require_storage_target_language_name,
59
+ )
56
60
  from context_aware_translation.storage.library.book_manager import BookManager
57
61
  from context_aware_translation.storage.models.book import Book
58
62
  from context_aware_translation.storage.models.config_profile import ConfigProfile
@@ -61,10 +65,6 @@ from context_aware_translation.storage.repositories.document_repository import D
61
65
  from context_aware_translation.storage.repositories.task_store import TaskRecord, TaskStore
62
66
  from context_aware_translation.storage.repositories.term_repository import TermRepository
63
67
  from context_aware_translation.storage.schema.book_db import SQLiteBookDB
64
- from context_aware_translation.ui.constants import (
65
- display_target_language_name,
66
- storage_target_language_name,
67
- )
68
68
  from context_aware_translation.workflow.tasks.models import TaskAction
69
69
 
70
70
  if TYPE_CHECKING:
@@ -900,9 +900,7 @@ def build_workflow_profile_payload(
900
900
  source_profile_id: str | None = None,
901
901
  ) -> dict[str, Any]:
902
902
  payload = dict(base_config or {})
903
- payload["translation_target_language"] = (
904
- storage_target_language_name(profile.target_language) or profile.target_language
905
- )
903
+ payload["translation_target_language"] = require_storage_target_language_name(profile.target_language)
906
904
  if source_profile_id:
907
905
  payload[_UI_SOURCE_PROFILE_ID_KEY] = source_profile_id
908
906
  else:
@@ -20,6 +20,7 @@ from context_aware_translation.workflow.ops import export_ops
20
20
  from context_aware_translation.workflow.session import WorkflowSession
21
21
 
22
22
  _INTERNAL_DOCUMENT_LABEL_PATHS = frozenset({"__epub_metadata__.json", "__epub_original__.epub"})
23
+ _NATIVE_FORMAT_ID = "native"
23
24
 
24
25
 
25
26
  @dataclass(frozen=True)
@@ -31,6 +32,7 @@ class PreparedExport:
31
32
  available_formats: list[ExportOption]
32
33
  default_output_path: str
33
34
  supports_preserve_structure: bool = False
35
+ requires_preserve_structure: bool = False
34
36
  supports_original_image_export: bool = False
35
37
  supports_epub_layout_conversion: bool = False
36
38
  incomplete_translation_message: str | None = None
@@ -89,15 +91,20 @@ def prepare_export(
89
91
  document_labels = [
90
92
  _document_label(int(doc["document_id"]), sources_by_doc.get(int(doc["document_id"]), [])) for doc in docs
91
93
  ]
92
- format_ids = list(get_supported_formats_for_type(document_type))
94
+ format_ids = _format_ids_for_export(
95
+ document_type=document_type,
96
+ document_ids=document_ids,
97
+ sources_by_doc=sources_by_doc,
98
+ )
93
99
  if not format_ids:
94
100
  raise_application_error(
95
101
  ApplicationErrorCode.UNSUPPORTED,
96
102
  f"No export formats are available for document type '{document_type}'.",
97
103
  )
104
+ requires_preserve_structure = _requires_preserve_structure(document_type)
98
105
  default_format = _preferred_default_format(document_type, format_ids, document_labels)
99
106
  available_formats = [
100
- ExportOption(format_id=fmt, label=fmt.upper(), is_default=(fmt == default_format)) for fmt in format_ids
107
+ ExportOption(format_id=fmt, label=_format_label(fmt), is_default=(fmt == default_format)) for fmt in format_ids
101
108
  ]
102
109
 
103
110
  incomplete = False
@@ -120,6 +127,7 @@ def prepare_export(
120
127
  project_id=project_id,
121
128
  document_labels=document_labels,
122
129
  default_format=default_format,
130
+ requires_preserve_structure=requires_preserve_structure,
123
131
  )
124
132
 
125
133
  return PreparedExport(
@@ -130,6 +138,7 @@ def prepare_export(
130
138
  available_formats=available_formats,
131
139
  default_output_path=default_output_path,
132
140
  supports_preserve_structure=supports_preserve_structure_for_type(document_type),
141
+ requires_preserve_structure=requires_preserve_structure,
133
142
  supports_original_image_export=supports_original_image_export_for_type(document_type),
134
143
  supports_epub_layout_conversion=document_type == "epub",
135
144
  incomplete_translation_message=(
@@ -148,6 +157,7 @@ def to_export_dialog_state(prepared: PreparedExport) -> ExportDialogState:
148
157
  available_formats=prepared.available_formats,
149
158
  default_output_path=prepared.default_output_path,
150
159
  supports_preserve_structure=prepared.supports_preserve_structure,
160
+ requires_preserve_structure=prepared.requires_preserve_structure,
151
161
  supports_original_image_export=prepared.supports_original_image_export,
152
162
  supports_epub_layout_conversion=prepared.supports_epub_layout_conversion,
153
163
  incomplete_translation_message=prepared.incomplete_translation_message,
@@ -165,7 +175,7 @@ def run_export(
165
175
  ) -> DocumentExportResult:
166
176
  prepared = prepare_export(runtime, project_id=project_id, document_ids=document_ids)
167
177
 
168
- preserve_structure = bool(options.get("preserve_structure", False))
178
+ preserve_structure = prepared.requires_preserve_structure or bool(options.get("preserve_structure", False))
169
179
  allow_original_fallback = bool(options.get("allow_original_fallback", False))
170
180
  use_original_images = bool(options.get("use_original_images", False))
171
181
  epub_force_horizontal_ltr = bool(options.get("epub_force_horizontal_ltr", False))
@@ -195,7 +205,7 @@ def run_export(
195
205
  )
196
206
  if not output_path.strip():
197
207
  raise_application_error(ApplicationErrorCode.VALIDATION, "Output path is required.", project_id=project_id)
198
- if not preserve_structure and format_id not in {option.format_id for option in prepared.available_formats}:
208
+ if format_id not in {option.format_id for option in prepared.available_formats}:
199
209
  raise_application_error(
200
210
  ApplicationErrorCode.VALIDATION,
201
211
  f"Unsupported export format: {format_id}.",
@@ -253,6 +263,29 @@ def _document_label(document_id: int, sources: list[dict]) -> str:
253
263
  return f"Document {document_id}"
254
264
 
255
265
 
266
+ def _format_ids_for_export(
267
+ *,
268
+ document_type: str,
269
+ document_ids: list[int],
270
+ sources_by_doc: dict[int, list[dict]],
271
+ ) -> list[str]:
272
+ format_ids = list(get_supported_formats_for_type(document_type))
273
+ _ = (document_ids, sources_by_doc)
274
+ if document_type == "galgame":
275
+ return [_NATIVE_FORMAT_ID] if _NATIVE_FORMAT_ID in format_ids else []
276
+ return format_ids
277
+
278
+
279
+ def _requires_preserve_structure(document_type: str) -> bool:
280
+ return document_type == "galgame"
281
+
282
+
283
+ def _format_label(format_id: str) -> str:
284
+ if format_id == _NATIVE_FORMAT_ID:
285
+ return "Native"
286
+ return format_id.upper()
287
+
288
+
256
289
  def _preferred_default_format(document_type: str, format_ids: list[str], document_labels: list[str]) -> str:
257
290
  if document_type == "subtitle" and len(document_labels) == 1:
258
291
  source_extension = Path(document_labels[0]).suffix.lower().lstrip(".")
@@ -267,11 +300,14 @@ def _default_output_path(
267
300
  project_id: str,
268
301
  document_labels: list[str],
269
302
  default_format: str,
303
+ requires_preserve_structure: bool,
270
304
  ) -> str:
271
305
  export_root = runtime.book_manager.get_book_path(project_id) / "export"
272
306
  base_name = "export"
273
307
  if len(document_labels) == 1:
274
308
  base_name = _slugify(Path(document_labels[0]).stem or document_labels[0]) or "export"
309
+ if requires_preserve_structure:
310
+ return str(export_root / base_name)
275
311
  return str(export_root / f"{base_name}.{default_format}")
276
312
 
277
313
 
@@ -38,6 +38,7 @@ from context_aware_translation.application.runtime import (
38
38
  recommended_workflow_profile_from_drafts,
39
39
  wizard_connection_key_for_draft,
40
40
  )
41
+ from context_aware_translation.languages import display_target_language_name
41
42
  from context_aware_translation.storage.models.config_profile import ConfigProfile
42
43
  from context_aware_translation.storage.models.endpoint_profile import EndpointProfile
43
44
 
@@ -133,7 +134,12 @@ class DefaultAppSetupService:
133
134
  target_language = current_detail.target_language
134
135
  requested_target_language = (request.target_language or "").strip()
135
136
  if requested_target_language:
136
- target_language = requested_target_language
137
+ target_language = display_target_language_name(requested_target_language) or ""
138
+ if not target_language:
139
+ raise_application_error(
140
+ ApplicationErrorCode.VALIDATION,
141
+ "Target language must be one of the supported language presets.",
142
+ )
137
143
  profile_name = (request.profile_name or "").strip() or None
138
144
  recommendation = recommended_workflow_profile_from_drafts(
139
145
  request.connections,
@@ -40,10 +40,12 @@ from context_aware_translation.application.contracts.document import (
40
40
  RunTranslateAndExportRequest,
41
41
  SaveOCRPageRequest,
42
42
  SaveTranslationRequest,
43
+ SaveTranslationsRequest,
43
44
  TranslateAndExportState,
44
45
  TranslationUnitActionState,
45
46
  TranslationUnitKind,
46
47
  TranslationUnitState,
48
+ TranslationUnitUpdate,
47
49
  )
48
50
  from context_aware_translation.application.contracts.terms import TermsTableState
49
51
  from context_aware_translation.application.errors import (
@@ -133,6 +135,8 @@ class DocumentService(Protocol):
133
135
 
134
136
  def save_translation(self, request: SaveTranslationRequest) -> DocumentTranslationState: ...
135
137
 
138
+ def save_translations(self, request: SaveTranslationsRequest) -> DocumentTranslationState: ...
139
+
136
140
  def retranslate(self, request: RetranslateRequest) -> AcceptedCommand: ...
137
141
 
138
142
  def run_translation(self, request: RunDocumentTranslationRequest) -> AcceptedCommand: ...
@@ -412,57 +416,76 @@ class DefaultDocumentService:
412
416
  )
413
417
 
414
418
  def save_translation(self, request: SaveTranslationRequest) -> DocumentTranslationState:
419
+ return self.save_translations(
420
+ SaveTranslationsRequest(
421
+ project_id=request.project_id,
422
+ document_id=request.document_id,
423
+ updates=[
424
+ TranslationUnitUpdate(
425
+ unit_id=request.unit_id,
426
+ translated_text=request.translated_text,
427
+ )
428
+ ],
429
+ )
430
+ )
431
+
432
+ def save_translations(self, request: SaveTranslationsRequest) -> DocumentTranslationState:
415
433
  with self._runtime.open_book_db(request.project_id) as dbx:
416
434
  doc = dbx.document_repo.get_document_by_id(request.document_id)
417
435
  if doc is None:
418
436
  raise_application_error(ApplicationErrorCode.NOT_FOUND, f"Document not found: {request.document_id}")
419
437
  blocker = self._translation_save_blocker(request.project_id, request.document_id)
420
438
  if blocker is not None:
421
- self._raise_blocked_blocker(blocker, document_id=request.document_id, unit_id=request.unit_id)
439
+ if len(request.updates) == 1:
440
+ self._raise_blocked_blocker(
441
+ blocker,
442
+ document_id=request.document_id,
443
+ unit_id=request.updates[0].unit_id,
444
+ )
445
+ self._raise_blocked_blocker(blocker, document_id=request.document_id)
422
446
 
423
447
  document_type = str(doc.get("document_type") or "")
424
- if document_type == "manga":
425
- chunk = self._resolve_manga_chunk_for_source(
426
- dbx=dbx,
427
- document_id=request.document_id,
428
- source_id=int(request.unit_id),
429
- )
430
- if chunk is None:
431
- raise_blocked_or_not_found_for_manga_unit(
432
- project_id=request.project_id,
448
+ updated_chunks: list[Any] = []
449
+ for update in request.updates:
450
+ if document_type == "manga":
451
+ chunk = self._resolve_manga_chunk_for_source(
452
+ dbx=dbx,
433
453
  document_id=request.document_id,
434
- source_id=int(request.unit_id),
454
+ source_id=int(update.unit_id),
435
455
  )
436
- updated_chunk = replace(
437
- chunk,
438
- is_translated=bool(request.translated_text.strip()),
439
- translation=request.translated_text if request.translated_text.strip() else None,
440
- )
441
- else:
442
- chunk = dbx.db.get_chunk_by_id(int(request.unit_id))
443
- if chunk is None or chunk.document_id is None or chunk.document_id != request.document_id:
444
- raise_application_error(
445
- ApplicationErrorCode.NOT_FOUND,
446
- f"Translation unit not found: {request.unit_id}",
447
- )
448
- source_line_count = self._line_count(chunk.text)
449
- translated_line_count = self._line_count(request.translated_text)
450
- if source_line_count > 0 and translated_line_count != source_line_count:
451
- raise_application_error(
452
- ApplicationErrorCode.VALIDATION,
453
- (
454
- f"Cannot save translation with {translated_line_count} lines; "
455
- f"expected {source_line_count} lines."
456
- ),
457
- document_id=request.document_id,
458
- unit_id=request.unit_id,
456
+ if chunk is None:
457
+ raise_blocked_or_not_found_for_manga_unit(
458
+ project_id=request.project_id,
459
+ document_id=request.document_id,
460
+ source_id=int(update.unit_id),
461
+ )
462
+ else:
463
+ chunk = dbx.db.get_chunk_by_id(int(update.unit_id))
464
+ if chunk is None or chunk.document_id is None or chunk.document_id != request.document_id:
465
+ raise_application_error(
466
+ ApplicationErrorCode.NOT_FOUND,
467
+ f"Translation unit not found: {update.unit_id}",
468
+ )
469
+ source_line_count = self._line_count(chunk.text)
470
+ translated_line_count = self._line_count(update.translated_text)
471
+ if source_line_count > 0 and translated_line_count != source_line_count:
472
+ raise_application_error(
473
+ ApplicationErrorCode.VALIDATION,
474
+ (
475
+ f"Cannot save translation with {translated_line_count} lines; "
476
+ f"expected {source_line_count} lines."
477
+ ),
478
+ document_id=request.document_id,
479
+ unit_id=update.unit_id,
480
+ )
481
+ updated_chunks.append(
482
+ replace(
483
+ chunk,
484
+ is_translated=bool(update.translated_text.strip()),
485
+ translation=update.translated_text if update.translated_text.strip() else None,
459
486
  )
460
- updated_chunk = replace(
461
- chunk,
462
- is_translated=bool(request.translated_text.strip()),
463
- translation=request.translated_text if request.translated_text.strip() else None,
464
487
  )
465
- dbx.db.upsert_chunks([updated_chunk])
488
+ dbx.db.upsert_chunks(updated_chunks)
466
489
  self._runtime.invalidate_document(
467
490
  request.project_id,
468
491
  request.document_id,
@@ -662,6 +685,7 @@ class DefaultDocumentService:
662
685
  available_formats=prepared.available_formats,
663
686
  default_output_path=prepared.default_output_path,
664
687
  supports_preserve_structure=prepared.supports_preserve_structure,
688
+ requires_preserve_structure=prepared.requires_preserve_structure,
665
689
  supports_original_image_export=prepared.supports_original_image_export,
666
690
  supports_epub_layout_conversion=prepared.supports_epub_layout_conversion,
667
691
  incomplete_translation_message=prepared.incomplete_translation_message,
@@ -726,6 +750,7 @@ class DefaultDocumentService:
726
750
  default_output_path=prepared.default_output_path,
727
751
  blocker=start_blocker,
728
752
  supports_preserve_structure=prepared.supports_preserve_structure,
753
+ requires_preserve_structure=prepared.requires_preserve_structure,
729
754
  supports_original_image_export=prepared.supports_original_image_export,
730
755
  supports_epub_layout_conversion=prepared.supports_epub_layout_conversion,
731
756
  batch_available=batch_blocker is None,
@@ -16,11 +16,11 @@ from context_aware_translation.application.runtime import (
16
16
  build_project_summary,
17
17
  raise_application_error,
18
18
  )
19
- from context_aware_translation.storage.models.book import BookStatus
20
- from context_aware_translation.ui.constants import (
19
+ from context_aware_translation.languages import (
21
20
  display_target_language_name,
22
21
  storage_target_language_name,
23
22
  )
23
+ from context_aware_translation.storage.models.book import BookStatus
24
24
 
25
25
 
26
26
  class ProjectsService(Protocol):
@@ -75,6 +75,11 @@ class DefaultProjectsService:
75
75
  )
76
76
 
77
77
  requested_target_language = storage_target_language_name(request.target_language)
78
+ if request.target_language is not None and requested_target_language is None:
79
+ raise_application_error(
80
+ ApplicationErrorCode.VALIDATION,
81
+ "Target language must be one of the supported language presets.",
82
+ )
78
83
  profile_for_defaults = requested_profile or self._runtime.get_default_profile()
79
84
  default_target_language = None
80
85
  if profile_for_defaults is not None:
@@ -127,11 +132,15 @@ class DefaultProjectsService:
127
132
  if updated is None:
128
133
  raise_application_error(ApplicationErrorCode.NOT_FOUND, f"Project not found: {request.project_id}")
129
134
  if request.target_language is not None:
135
+ target_language = storage_target_language_name(request.target_language)
136
+ if target_language is None:
137
+ raise_application_error(
138
+ ApplicationErrorCode.VALIDATION,
139
+ "Target language must be one of the supported language presets.",
140
+ )
130
141
  book = self._runtime.get_book(request.project_id)
131
142
  config = self._runtime.get_effective_config_payload(request.project_id)
132
- config["translation_target_language"] = (
133
- storage_target_language_name(request.target_language) or request.target_language
134
- )
143
+ config["translation_target_language"] = target_language
135
144
  if book.profile_id is not None:
136
145
  config["_ui_source_profile_id"] = book.profile_id
137
146
  self._runtime.book_manager.set_book_custom_config(request.project_id, config)
@@ -208,7 +208,15 @@ class DefaultWorkService:
208
208
  elif total_chunks > 0 and translated_chunks == total_chunks:
209
209
  status = SurfaceStatus.DONE
210
210
  summary = "Ready to export"
211
- action = DocumentRowAction(kind=DocumentRowActionKind.EXPORT, label="Export")
211
+ action = DocumentRowAction(
212
+ kind=DocumentRowActionKind.EXPORT,
213
+ label="Export",
214
+ target=NavigationTarget(
215
+ kind=NavigationTargetKind.DOCUMENT_EXPORT,
216
+ project_id=project_id,
217
+ document_id=document_id,
218
+ ),
219
+ )
212
220
  frontier_last_ready = ref
213
221
  else:
214
222
  status = SurfaceStatus.READY
@@ -12,6 +12,7 @@ from context_aware_translation.app_identity import default_user_config_dir
12
12
  from context_aware_translation.application.contracts.app_setup import ConnectionDraft, WorkflowProfileDetail
13
13
  from context_aware_translation.application.runtime import build_workflow_profile_payload
14
14
  from context_aware_translation.config import EndpointProfile, ensure_valid_persisted_config_payload
15
+ from context_aware_translation.languages import storage_target_language_name
15
16
 
16
17
  from .output import EXIT_USAGE, CliError
17
18
 
@@ -218,6 +219,13 @@ def load_cli_config(path: Path) -> ResolvedCliConfig:
218
219
  )
219
220
 
220
221
  profile = WorkflowProfileDetail.model_validate(profile_payload)
222
+ if storage_target_language_name(profile.target_language) is None:
223
+ raise CliError(
224
+ "invalid_config",
225
+ "target_language must be one of the supported language presets.",
226
+ exit_code=EXIT_USAGE,
227
+ details={"target_language": profile.target_language},
228
+ )
221
229
  _validate_route_connections(profile, endpoint_profiles)
222
230
  custom_config = build_workflow_profile_payload(base_config=None, profile=profile)
223
231
  custom_config["endpoint_profiles"] = {
@@ -4,6 +4,7 @@ import argparse
4
4
  from pathlib import Path
5
5
  from typing import Any, cast
6
6
 
7
+ from context_aware_translation import configure_standard_streams
7
8
  from context_aware_translation.application.contracts.common import ContractModel
8
9
  from context_aware_translation.application.contracts.document import RunTranslateAndExportRequest
9
10
  from context_aware_translation.application.contracts.work import ImportDocumentsRequest, InspectImportPathsRequest
@@ -36,6 +37,7 @@ def main() -> None:
36
37
 
37
38
 
38
39
  def run(argv: list[str] | None = None) -> int:
40
+ configure_standard_streams()
39
41
  parser = build_parser()
40
42
  args = parser.parse_args(argv)
41
43
  command = command_name(args)
@@ -10,6 +10,10 @@ from typing import TYPE_CHECKING, Any, Protocol, TypeVar
10
10
  import yaml
11
11
 
12
12
  from context_aware_translation import configure_logging
13
+ from context_aware_translation.languages import (
14
+ require_storage_target_language_name,
15
+ storage_target_language_name,
16
+ )
13
17
  from context_aware_translation.llm.image_generator import ImageBackend
14
18
 
15
19
  if TYPE_CHECKING:
@@ -980,6 +984,7 @@ class Config:
980
984
  )
981
985
 
982
986
  def __post_init__(self) -> None:
987
+ self.translation_target_language = require_storage_target_language_name(self.translation_target_language)
983
988
  self.output_dir = Path(self.output_dir)
984
989
  if self.working_dir is None:
985
990
  self.working_dir = self.output_dir / DEFAULT_WORKING_SUBDIR
@@ -1148,6 +1153,8 @@ def validate_persisted_config_payload(
1148
1153
  target_language = config.get("translation_target_language")
1149
1154
  if not isinstance(target_language, str) or target_language.strip() == "":
1150
1155
  errors.append("translation_target_language is required")
1156
+ elif storage_target_language_name(target_language) is None:
1157
+ errors.append("translation_target_language must be one of the supported language presets")
1151
1158
 
1152
1159
  endpoint_profiles = config.get("endpoint_profiles", {})
1153
1160
  if endpoint_profiles is None:
@@ -321,6 +321,19 @@ class ContextManager:
321
321
 
322
322
  return " ".join(value for index, (_key, value) in enumerate(entries) if index in selected_indexes).strip()
323
323
 
324
+ def _latest_raw_description(self, descriptions: dict[str, str], *, query_index: int) -> str:
325
+ """Return one causal description for a lightweight translation prompt."""
326
+ entries = self._ordered_description_entries(descriptions, query_index=query_index)
327
+ numeric_values = [value for key, value in entries if (idx := description_index(key)) is not None and idx >= 0]
328
+ if numeric_values:
329
+ description = numeric_values[-1]
330
+ else:
331
+ description = next(
332
+ (value for key, value in entries if description_index(key) == -1),
333
+ "",
334
+ )
335
+ return self._truncate_description(description, self.max_term_description_length)
336
+
324
337
  @staticmethod
325
338
  def _term_requires_term_memory(term: Term) -> bool:
326
339
  return term.term_type in {"character", "organization"}
@@ -572,7 +585,7 @@ class ContextManager:
572
585
  def get_term_description_for_query(self, term: Term, query_index: int) -> str:
573
586
  """Return the term description text used for chunk translation prompts."""
574
587
  if not self._term_requires_term_memory(term):
575
- return self._compact_raw_description(term.descriptions, query_index=query_index)
588
+ return self._latest_raw_description(term.descriptions, query_index=query_index)
576
589
  description = self._best_available_summary(
577
590
  term,
578
591
  query_index,