ok-script 2.0.20__tar.gz → 2.0.22__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 (400) hide show
  1. {ok_script-2.0.20 → ok_script-2.0.22}/PKG-INFO +1 -1
  2. {ok_script-2.0.20 → ok_script-2.0.22}/docs/mcp.md +10 -1
  3. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/code_runner.py +1 -1
  4. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/mcp_runner.py +66 -1
  5. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/mcp_server.py +4 -2
  6. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/start_controller.py +4 -4
  7. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/MainWindow.py +1 -1
  8. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/en_US.qm +0 -0
  9. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/en_US.ts +151 -0
  10. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/es_ES.qm +0 -0
  11. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/es_ES.ts +151 -0
  12. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ja_JP.qm +0 -0
  13. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ja_JP.ts +151 -0
  14. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ko_KR.qm +0 -0
  15. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ko_KR.ts +151 -0
  16. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_CN.qm +0 -0
  17. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_CN.ts +151 -0
  18. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_TW.qm +0 -0
  19. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_TW.ts +151 -0
  20. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/plugins/PluginTab.py +2 -2
  21. ok_script-2.0.22/ok/ui/qt/resources.py +19088 -0
  22. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/EditTaskTab.py +6 -6
  23. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/StartButton.py +1 -1
  24. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TemplateFactory.py +1 -1
  25. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TemplateTab.py +3 -2
  26. {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/PKG-INFO +1 -1
  27. {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/SOURCES.txt +1 -0
  28. ok_script-2.0.22/tests/test_mcp_cleanup.py +166 -0
  29. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mcp_server.py +35 -0
  30. ok_script-2.0.22/tests/test_translation_fallback.py +222 -0
  31. ok_script-2.0.20/ok/ui/qt/resources.py +0 -17921
  32. ok_script-2.0.20/tests/test_translation_fallback.py +0 -119
  33. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/develop/SKILL.md +0 -0
  34. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/develop/agents/openai.yaml +0 -0
  35. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/develop/references/windows-input.md +0 -0
  36. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/generate-templates/SKILL.md +0 -0
  37. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/reload-tasks/SKILL.md +0 -0
  38. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/reload-tasks/agents/openai.yaml +0 -0
  39. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-env/SKILL.md +0 -0
  40. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-env/agents/openai.yaml +0 -0
  41. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-env/assets/ok-script-develop/SKILL.md +0 -0
  42. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-project/SKILL.md +0 -0
  43. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-project/agents/openai.yaml +0 -0
  44. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/use_venv/SKILL.md +0 -0
  45. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/write-test/SKILL.md +0 -0
  46. {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/write-test/agents/openai.yaml +0 -0
  47. {ok_script-2.0.20 → ok_script-2.0.22}/LICENSE.txt +0 -0
  48. {ok_script-2.0.20 → ok_script-2.0.22}/MANIFEST.in +0 -0
  49. {ok_script-2.0.20 → ok_script-2.0.22}/README.md +0 -0
  50. {ok_script-2.0.20 → ok_script-2.0.22}/diagnostics/qq_trace.py +0 -0
  51. {ok_script-2.0.20 → ok_script-2.0.22}/docs/agent-setup.md +0 -0
  52. {ok_script-2.0.20 → ok_script-2.0.22}/docs/feature-crops.md +0 -0
  53. {ok_script-2.0.20 → ok_script-2.0.22}/examples/mcp_observe.py +0 -0
  54. {ok_script-2.0.20 → ok_script-2.0.22}/ok/__init__.py +0 -0
  55. {ok_script-2.0.20 → ok_script-2.0.22}/ok/__main__.py +0 -0
  56. {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/__init__.py +0 -0
  57. {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/emulator_base.py +0 -0
  58. {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/emulator_windows.py +0 -0
  59. {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/platform_windows.py +0 -0
  60. {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/utils.py +0 -0
  61. {ok_script-2.0.20 → ok_script-2.0.22}/ok/assets/default-icon.png +0 -0
  62. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/__init__.py +0 -0
  63. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/__init__.py +0 -0
  64. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/deep.py +0 -0
  65. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/minitouch.py +0 -0
  66. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/nemu_ipc.py +0 -0
  67. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/nemu_utils.py +0 -0
  68. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/pool.py +0 -0
  69. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/timer.py +0 -0
  70. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/util.py +0 -0
  71. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/windows/__init__.py +0 -0
  72. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/windows/d3d11.py +0 -0
  73. {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/windows/dump.py +0 -0
  74. {ok_script-2.0.20 → ok_script-2.0.22}/ok/cli.py +0 -0
  75. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/__init__.py +0 -0
  76. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/capture_labels.py +0 -0
  77. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/config_schema.py +0 -0
  78. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/downloads.py +0 -0
  79. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/events.py +0 -0
  80. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/icons.py +0 -0
  81. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/notifications.py +0 -0
  82. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/plugin_staging.py +0 -0
  83. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/plugins.py +0 -0
  84. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/screenshot.py +0 -0
  85. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/script_editing.py +0 -0
  86. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/script_packager.py +0 -0
  87. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/script_templates.py +0 -0
  88. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/skills.py +0 -0
  89. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/task_manager.py +0 -0
  90. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/template_store.py +0 -0
  91. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/translation.py +0 -0
  92. {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/ui_config.py +0 -0
  93. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/DeviceManager.py +0 -0
  94. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/__init__.py +0 -0
  95. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture.py +0 -0
  96. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/__init__.py +0 -0
  97. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/adb.py +0 -0
  98. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/base.py +0 -0
  99. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/bitblt.py +0 -0
  100. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/bitblt_utils.py +0 -0
  101. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/browser.py +0 -0
  102. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/desktop_duplication.py +0 -0
  103. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/hwnd_window.py +0 -0
  104. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/image.py +0 -0
  105. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/nemu_ipc.py +0 -0
  106. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/types.py +0 -0
  107. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/update.py +0 -0
  108. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/windows_graphics.py +0 -0
  109. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/windows_graphics_hdr.py +0 -0
  110. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction.py +0 -0
  111. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/__init__.py +0 -0
  112. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/adb.py +0 -0
  113. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/base.py +0 -0
  114. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/browser.py +0 -0
  115. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/do_nothing.py +0 -0
  116. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/foreground_post_message.py +0 -0
  117. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/genshin.py +0 -0
  118. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/keys.py +0 -0
  119. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/post_message.py +0 -0
  120. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/pydirect.py +0 -0
  121. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/pynput.py +0 -0
  122. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/swipe.py +0 -0
  123. {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/intercation.py +0 -0
  124. {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/Box.py +0 -0
  125. {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/Feature.py +0 -0
  126. {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/FeatureSet.py +0 -0
  127. {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/__init__.py +0 -0
  128. {ok_script-2.0.20 → ok_script-2.0.22}/ok/gui/__init__.py +0 -0
  129. {ok_script-2.0.20 → ok_script-2.0.22}/ok/gui/util/pyappify_startup.py +0 -0
  130. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/__init__.py +0 -0
  131. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/manager.py +0 -0
  132. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/messenger_images.py +0 -0
  133. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/pipeline.py +0 -0
  134. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/ppocr.py +0 -0
  135. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/providers.py +0 -0
  136. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/system.py +0 -0
  137. {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/windows_messenger.py +0 -0
  138. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ocr/__init__.py +0 -0
  139. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ocr/download_paddle_model.py +0 -0
  140. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  141. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  142. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  143. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  144. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  145. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  146. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  147. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  148. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  149. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Media/__init__.py +0 -0
  150. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  151. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Security/__init__.py +0 -0
  152. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  153. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  154. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/UI/ViewManagement/__init__.py +0 -0
  155. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/UI/__init__.py +0 -0
  156. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/__init__.py +0 -0
  157. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/__init__.py +0 -0
  158. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/delegate.py +0 -0
  159. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/export.py +0 -0
  160. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/idldsl.py +0 -0
  161. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/inspectable.py +0 -0
  162. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/roapi.py +0 -0
  163. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/types.py +0 -0
  164. {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/winstring.py +0 -0
  165. {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/DiagnosisTask.py +0 -0
  166. {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/TaskExecutor.py +0 -0
  167. {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/__init__.py +0 -0
  168. {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/exceptions.py +0 -0
  169. {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/task.py +0 -0
  170. {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/OKTestRunner.py +0 -0
  171. {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/RunTests.py +0 -0
  172. {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/TaskTestCase.py +0 -0
  173. {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/__init__.py +0 -0
  174. {ok_script-2.0.20 → ok_script-2.0.22}/ok/third_party/__init__.py +0 -0
  175. {ok_script-2.0.20 → ok_script-2.0.22}/ok/third_party/paperclip.py +0 -0
  176. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/__init__.py +0 -0
  177. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/overlay/__init__.py +0 -0
  178. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/overlay/win32_gdi.py +0 -0
  179. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/Communicate.py +0 -0
  180. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/MessageWindow.py +0 -0
  181. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/StartController.py +0 -0
  182. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/TabTitles.py +0 -0
  183. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/__init__.py +0 -0
  184. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/AboutTab.py +0 -0
  185. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/HttpTextEdit.py +0 -0
  186. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/LinksBar.py +0 -0
  187. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/ProjectCard.py +0 -0
  188. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/UpdateCard.py +0 -0
  189. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/VersionCard.py +0 -0
  190. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/__init__.py +0 -0
  191. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/OKIcon.py +0 -0
  192. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/__init__.py +0 -0
  193. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/accent_color.py +0 -0
  194. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/config.py +0 -0
  195. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/design_system.py +0 -0
  196. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/icons.py +0 -0
  197. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/style_sheet.py +0 -0
  198. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/DebugTab.py +0 -0
  199. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/JobControls.py +0 -0
  200. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/OverlayWidget.py +0 -0
  201. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/RunCodeTab.py +0 -0
  202. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/Screenshot.py +0 -0
  203. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/__init__.py +0 -0
  204. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/events.py +0 -0
  205. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/GettextTranslator.py +0 -0
  206. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/__init__.py +0 -0
  207. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/path.py +0 -0
  208. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/update.py +0 -0
  209. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/overlay/OverlayWindow.py +0 -0
  210. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/overlay/__init__.py +0 -0
  211. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/plugins/__init__.py +0 -0
  212. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/plugins/imported_tabs.py +0 -0
  213. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/__init__.py +0 -0
  214. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/card.qss +0 -0
  215. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/discord.svg +0 -0
  216. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/heart.svg +0 -0
  217. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/message_window.qss +0 -0
  218. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/setting_interface.qss +0 -0
  219. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/status_bar.qss +0 -0
  220. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/stop.svg +0 -0
  221. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/tab.qss +0 -0
  222. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/card.qss +0 -0
  223. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/discord.svg +0 -0
  224. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/heart.svg +0 -0
  225. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/message_window.qss +0 -0
  226. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/setting_interface.qss +0 -0
  227. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/status_bar.qss +0 -0
  228. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/stop.svg +0 -0
  229. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/tab.qss +0 -0
  230. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qt.qrc +0 -0
  231. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/GlobalConfigCard.py +0 -0
  232. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/GlobalConfigTab.py +0 -0
  233. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/SettingTab.py +0 -0
  234. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/__init__.py +0 -0
  235. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/LogWindow.py +0 -0
  236. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/SelectCaptureListView.py +0 -0
  237. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/SelectInteractionListView.py +0 -0
  238. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/StartCard.py +0 -0
  239. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/StartTab.py +0 -0
  240. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/__init__.py +0 -0
  241. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ConfigCard.py +0 -0
  242. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ConfigItemFactory.py +0 -0
  243. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ConfigLabelAndWidget.py +0 -0
  244. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndButtons.py +0 -0
  245. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndDoubleSpinBox.py +0 -0
  246. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndDropDown.py +0 -0
  247. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndFileSelector.py +0 -0
  248. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndGlobal.py +0 -0
  249. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndLineEdit.py +0 -0
  250. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndList.py +0 -0
  251. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndMcpServer.py +0 -0
  252. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndMultiSelection.py +0 -0
  253. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndSpinBox.py +0 -0
  254. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndSwitchButton.py +0 -0
  255. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndTextEdit.py +0 -0
  256. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndWidget.py +0 -0
  257. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/MarkUpWindow.py +0 -0
  258. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ModifyListDialog.py +0 -0
  259. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ModifyListItem.py +0 -0
  260. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/OneTimeTaskTab.py +0 -0
  261. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/PythonHighlighter.py +0 -0
  262. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/RecordScript.py +0 -0
  263. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ScheduleTaskTab.py +0 -0
  264. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ScriptPackager.py +0 -0
  265. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskCard.py +0 -0
  266. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskManger.py +0 -0
  267. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskOpButton.py +0 -0
  268. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskTab.py +0 -0
  269. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TooltipTableWidget.py +0 -0
  270. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TriggerTaskTab.py +0 -0
  271. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/__init__.py +0 -0
  272. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/schedule_index_sync.py +0 -0
  273. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/Alert.py +0 -0
  274. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/InitWorker.py +0 -0
  275. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/__init__.py +0 -0
  276. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/app.py +0 -0
  277. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/download.py +0 -0
  278. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/pip_util.py +0 -0
  279. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/pyappify_startup.py +0 -0
  280. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/touch_scroll.py +0 -0
  281. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/windows_thumbnail.py +0 -0
  282. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/BaseLoading.py +0 -0
  283. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/BaseWindow.py +0 -0
  284. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/Card.py +0 -0
  285. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/CustomTab.py +0 -0
  286. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/EmptyCard.py +0 -0
  287. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ExpandCardLayout.py +0 -0
  288. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/FlowLayout.py +0 -0
  289. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/FramelessDialog.py +0 -0
  290. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ImageWidget.py +0 -0
  291. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ImportWarningDialog.py +0 -0
  292. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ListTableWidgetItem.py +0 -0
  293. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/NumericTableWidgetItem.py +0 -0
  294. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/OkCompactSpinBox.py +0 -0
  295. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/SortingTableWidgetItem.py +0 -0
  296. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/StartLoadingDialog.py +0 -0
  297. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/StatusBar.py +0 -0
  298. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/Tab.py +0 -0
  299. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/TabWidget.py +0 -0
  300. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/UpdateConfigWidgetItem.py +0 -0
  301. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/WidgetWithVLabel.py +0 -0
  302. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/YesNonWidgetItem.py +0 -0
  303. {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/__init__.py +0 -0
  304. {ok_script-2.0.20 → ok_script-2.0.22}/ok/update/__init__.py +0 -0
  305. {ok_script-2.0.20 → ok_script-2.0.22}/ok/update/copy_ok_folder.py +0 -0
  306. {ok_script-2.0.20 → ok_script-2.0.22}/ok/update/inline_ok_requirements.py +0 -0
  307. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/Analytics.py +0 -0
  308. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/GlobalConfig.py +0 -0
  309. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/__init__.py +0 -0
  310. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/blur.py +0 -0
  311. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/clazz.py +0 -0
  312. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/collection.py +0 -0
  313. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/color.py +0 -0
  314. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/config.py +0 -0
  315. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/explorer.py +0 -0
  316. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/file.py +0 -0
  317. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/gpu_driver_settings.py +0 -0
  318. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/handler.py +0 -0
  319. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/i18n.py +0 -0
  320. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/logger.py +0 -0
  321. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/partial_sync_repo.py +0 -0
  322. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/print_hwnd.py +0 -0
  323. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/process.py +0 -0
  324. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/version.py +0 -0
  325. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/window.py +0 -0
  326. {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/windows_schedule.py +0 -0
  327. {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/dependency_links.txt +0 -0
  328. {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/entry_points.txt +0 -0
  329. {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/not-zip-safe +0 -0
  330. {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/requires.txt +0 -0
  331. {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/top_level.txt +0 -0
  332. {ok_script-2.0.20 → ok_script-2.0.22}/pyproject.toml +0 -0
  333. {ok_script-2.0.20 → ok_script-2.0.22}/setup.cfg +0 -0
  334. {ok_script-2.0.20 → ok_script-2.0.22}/setup.py +0 -0
  335. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_accent_color.py +0 -0
  336. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_app.py +0 -0
  337. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_base_interaction.py +0 -0
  338. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_blur.py +0 -0
  339. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_box.py +0 -0
  340. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_capture_update.py +0 -0
  341. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_cli.py +0 -0
  342. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_config_card.py +0 -0
  343. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_core_events.py +0 -0
  344. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_core_ui_services.py +0 -0
  345. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_debug_job_controls.py +0 -0
  346. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_device_manager.py +0 -0
  347. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_executor_jobs.py +0 -0
  348. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_expand_card_layout.py +0 -0
  349. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_explorer.py +0 -0
  350. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_global_config.py +0 -0
  351. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_gpu_driver_settings.py +0 -0
  352. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_handler.py +0 -0
  353. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_headless_imports.py +0 -0
  354. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_inline_ok_requirements.py +0 -0
  355. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_logger.py +0 -0
  356. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_main_window_notifications.py +0 -0
  357. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_main_window_startup_tab.py +0 -0
  358. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_main_window_system_theme.py +0 -0
  359. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mcp_runner.py +0 -0
  360. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mcp_setting.py +0 -0
  361. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_missing_frame.py +0 -0
  362. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mouse_buttons.py +0 -0
  363. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_navigation_state.py +0 -0
  364. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_nemu_ipc_capture.py +0 -0
  365. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_notifications.py +0 -0
  366. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_ok_mutex.py +0 -0
  367. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_overlay_custom_draw.py +0 -0
  368. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_overlay_lifecycle.py +0 -0
  369. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_package_metadata.py +0 -0
  370. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_plugin_staging.py +0 -0
  371. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_plugin_tabs.py +0 -0
  372. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_plugins.py +0 -0
  373. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_process.py +0 -0
  374. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_process_mutex.py +0 -0
  375. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_pyappify_startup_update.py +0 -0
  376. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_qt_events.py +0 -0
  377. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_qt_legacy_imports.py +0 -0
  378. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_qt_page_layout.py +0 -0
  379. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_runtime_startup.py +0 -0
  380. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_schedule_startup.py +0 -0
  381. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_schedule_task_index_sync.py +0 -0
  382. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_screenshot_naming.py +0 -0
  383. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_screenshot_rendering.py +0 -0
  384. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_skills.py +0 -0
  385. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_start_controller.py +0 -0
  386. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_start_tab_overlay.py +0 -0
  387. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_executor_next_frame.py +0 -0
  388. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_executor_queue.py +0 -0
  389. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_reloading.py +0 -0
  390. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_ui.py +0 -0
  391. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_template_compression.py +0 -0
  392. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_template_generation.py +0 -0
  393. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_template_tab.py +0 -0
  394. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_touch_scroll.py +0 -0
  395. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_ui_config.py +0 -0
  396. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_version.py +0 -0
  397. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_graphics_capture.py +0 -0
  398. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_graphics_hdr.py +0 -0
  399. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_schedule_target_parse.py +0 -0
  400. {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_schedule_xml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ok-script
3
- Version: 2.0.20
3
+ Version: 2.0.22
4
4
  Summary: Automation with Computer Vision for Python
5
5
  Author-email: ok-oldking <firedcto@gmail.com>
6
6
  License: ok-script License
@@ -72,6 +72,15 @@ Applications using `OK(config).start()` can enable MCP through their config:
72
72
  "mcp": {"enabled": True, "port": 8765, "artifact_directory": "logs/mcp"}
73
73
  ```
74
74
 
75
+ MCP artifacts use a seven-day retention period by default. Set `mcp.retention_days`
76
+ to a nonnegative number of days, or `0` to disable cleanup. Cleanup runs on startup
77
+ and at most once per hour when submitting runs/reloads or requesting screenshots.
78
+ It removes expired completed run directories (including their logs, status and
79
+ custom artifacts), their in-memory status records, and old observation images.
80
+ Run age is measured from `finished_at`; observation age uses the image file's
81
+ modification time. Active/nonterminal runs, unrecognized files and connection
82
+ records are preserved. Copy evidence elsewhere if it must outlive retention.
83
+
75
84
  The server binds only to IPv4 loopback and validates HTTP Host and Origin.
76
85
  Each instance writes `logs/mcp/connections/<pid>-<port>.json` containing its URL,
77
86
  bearer token, process ID, process start time and project directory. These records
@@ -143,7 +152,7 @@ Clients supporting MCP resources can also discover these skills through
143
152
 
144
153
  States are `queued`, `running`, `stopping`, `succeeded`, `failed`, and
145
154
  `cancelled`. Only the last three are terminal. Run IDs are scoped to the current
146
- process; saved artifacts remain available after restarting it.
155
+ process; saved artifacts remain available after restarting it until retention cleanup.
147
156
 
148
157
  ## Preferred workflow for existing tasks
149
158
 
@@ -24,7 +24,7 @@ from typing import Any
24
24
 
25
25
  from ok.task.exceptions import TaskDisabledException
26
26
 
27
- _log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', datefmt='%H:%M:%S')
27
+ _log_formatter = logging.Formatter('%(asctime)s.%(msecs)03d %(levelname)s %(message)s', datefmt='%H:%M:%S')
28
28
  _capture_lock = threading.Lock()
29
29
  _run_ids = itertools.count(1)
30
30
 
@@ -4,6 +4,9 @@ import hashlib
4
4
  import importlib.util
5
5
  import inspect
6
6
  import json
7
+ import math
8
+ import re
9
+ import shutil
7
10
  import sys
8
11
  import threading
9
12
  import time
@@ -15,9 +18,11 @@ from pathlib import Path
15
18
  from ok.core.code_runner import capture_output
16
19
  from ok.task.exceptions import TaskDisabledException
17
20
  from ok.task.task import BaseTask, TriggerTask
21
+ from ok.util.logger import Logger
18
22
 
19
23
 
20
24
  TERMINAL_STATES = {'succeeded', 'failed', 'cancelled'}
25
+ logger = Logger.get_logger(__name__)
21
26
 
22
27
 
23
28
  class McpTaskRunner:
@@ -30,7 +35,10 @@ class McpTaskRunner:
30
35
  """
31
36
 
32
37
  def __init__(self, executor, app, screenshot_service, artifact_directory='logs/mcp', prepare=None,
33
- task_manager=None):
38
+ task_manager=None, retention_days=7):
39
+ if (isinstance(retention_days, bool) or not isinstance(retention_days, (int, float))
40
+ or not math.isfinite(retention_days) or retention_days < 0):
41
+ raise ValueError('mcp.retention_days must be a finite nonnegative number')
34
42
  self.executor = executor
35
43
  self.app = app
36
44
  self.screenshot_service = screenshot_service
@@ -42,8 +50,63 @@ class McpTaskRunner:
42
50
  self._active = None
43
51
  self._observation_job = None
44
52
  self._closed = False
53
+ self.retention_days = retention_days
54
+ self._next_cleanup = 0
55
+ self._cleanup_artifacts()
45
56
  self.executor.enable_frame_snapshots()
46
57
 
58
+ def _cleanup_artifacts(self):
59
+ """Expire completed runs and observations, at most hourly during activity."""
60
+ with self._lock:
61
+ now = time.monotonic()
62
+ if self.retention_days == 0 or now < self._next_cleanup:
63
+ return
64
+ self._next_cleanup = now + 3600
65
+ cutoff = time.time() - self.retention_days * 86400
66
+ try:
67
+ paths = list(self.artifact_directory.iterdir())
68
+ except FileNotFoundError:
69
+ return
70
+ except OSError as error:
71
+ logger.warning(f'Could not scan MCP artifacts: {error}')
72
+ return
73
+ for path in paths:
74
+ try:
75
+ # Only operate on framework-owned entries inside this root.
76
+ # In particular, never follow directory links or junctions.
77
+ if path.is_symlink() or path.resolve() != path:
78
+ continue
79
+ if path.name == 'observations' and path.is_dir():
80
+ for image in path.iterdir():
81
+ if (re.fullmatch(r'[0-9a-f]{32}\.png', image.name)
82
+ and not image.is_symlink() and image.is_file()
83
+ and image.resolve() == image
84
+ and image.stat().st_mtime < cutoff):
85
+ try:
86
+ image.unlink()
87
+ except OSError as error:
88
+ logger.warning(f'Could not remove MCP observation {image}: {error}')
89
+ elif (re.fullmatch(r'[0-9a-f]{32}', path.name) and path.is_dir()
90
+ and path.name != self._active):
91
+ try:
92
+ record = json.loads((path / 'status.json').read_text(encoding='utf-8'))
93
+ except (ValueError, UnicodeError):
94
+ continue
95
+ if not isinstance(record, dict):
96
+ continue
97
+ finished = record.get('finished_at')
98
+ if (record.get('run_id') == path.name
99
+ and isinstance(record.get('state'), str)
100
+ and record['state'] in TERMINAL_STATES
101
+ and isinstance(finished, (int, float)) and not isinstance(finished, bool)
102
+ and math.isfinite(finished) and finished < cutoff):
103
+ shutil.rmtree(path)
104
+ self._runs.pop(path.name, None)
105
+ except FileNotFoundError:
106
+ pass # Another server sharing this directory may have removed it.
107
+ except OSError as error:
108
+ logger.warning(f'Could not clean MCP artifacts {path}: {error}')
109
+
47
110
  def _save(self, record):
48
111
  path = Path(record['artifact_directory']) / 'status.json'
49
112
  temporary = path.with_suffix('.tmp')
@@ -135,6 +198,7 @@ class McpTaskRunner:
135
198
  raise RuntimeError('MCP task runner is shutting down')
136
199
  if self._active is not None:
137
200
  raise RuntimeError(f'Run {self._active} is still active; wait until it has stopped')
201
+ self._cleanup_artifacts()
138
202
  run_id = uuid.uuid4().hex
139
203
  owner = f'mcp:{run_id}'
140
204
  self.executor.acquire_exclusive(owner)
@@ -282,6 +346,7 @@ class McpTaskRunner:
282
346
  with self._lock:
283
347
  if self._closed:
284
348
  raise RuntimeError('MCP task runner is shutting down')
349
+ self._cleanup_artifacts()
285
350
  if (self._active is None and self._observation_job is None and self.executor.current_job is None
286
351
  and self.executor.current_task is None and self.executor.exclusive_owner is None):
287
352
  def capture():
@@ -232,7 +232,7 @@ class LocalMcpServer:
232
232
  app = runtime.headless_app if runtime.should_init_task_manager_headless() else runtime.app
233
233
  self.runner = McpTaskRunner(runtime.task_executor, app, runtime.screenshot,
234
234
  config.get('artifact_directory', 'logs/mcp'), self._prepare_device,
235
- task_manager=og.task_manager)
235
+ task_manager=og.task_manager, retention_days=config.get('retention_days', 7))
236
236
  self._server = None
237
237
  self._socket = None
238
238
  self._thread = None
@@ -289,9 +289,11 @@ class LocalMcpServer:
289
289
  self.port = self._socket.getsockname()[1]
290
290
  app = create_mcp_app(self.runner, self.token, self.port, self.exit_process)
291
291
  import uvicorn
292
+ # uvicorn's default log_config goes through dictConfig, which closes every
293
+ # existing handler in the process, including the ok-script.log file handler.
292
294
  self._server = uvicorn.Server(uvicorn.Config(
293
295
  app, host='127.0.0.1', port=self.port, log_level='warning', access_log=False,
294
- timeout_graceful_shutdown=5))
296
+ log_config=None, timeout_graceful_shutdown=5))
295
297
 
296
298
  def serve():
297
299
  try:
@@ -88,7 +88,7 @@ class StartController:
88
88
  return True
89
89
  except Exception as e:
90
90
  logger.error(f'do_start resume exception: {e}', e)
91
- communicate.starting_emulator.emit(True, self.tr(f'Start failed: {e}'), 0)
91
+ communicate.starting_emulator.emit(True, self.tr('Start failed: {error}').format(error=e), 0)
92
92
  return False
93
93
 
94
94
  try:
@@ -130,7 +130,7 @@ class StartController:
130
130
  return True
131
131
  except Exception as e:
132
132
  logger.error(f'do_start exception: {e}', e)
133
- communicate.starting_emulator.emit(True, self.tr(f'Start failed: {e}'), 0)
133
+ communicate.starting_emulator.emit(True, self.tr('Start failed: {error}').format(error=e), 0)
134
134
  return False
135
135
 
136
136
  def _wait_until_device_ready(self, refresh_first=True):
@@ -190,7 +190,7 @@ class StartController:
190
190
  if device and not device['connected']:
191
191
  if device['device'] == "windows" and not is_admin():
192
192
  communicate.starting_emulator.emit(True,
193
- "PC version requires admin privileges, Please restart this app with admin privileges!",
193
+ self.tr("PC version requires admin privileges, Please restart this app with admin privileges!"),
194
194
  0)
195
195
  communicate.restart_admin.emit()
196
196
  return False
@@ -353,7 +353,7 @@ class StartController:
353
353
  hwnd_window.do_update_window_size()
354
354
  if not og.device_manager.capture_method.hwnd_window.pos_valid:
355
355
  return self.tr(
356
- f'Window is minimized or out of screen, and don\'t use full-screen exclusive mode!')
356
+ 'Window is minimized or out of screen, and don\'t use full-screen exclusive mode!')
357
357
  frame = self.try_capture_a_frame()
358
358
  if frame is None:
359
359
  logger.error(f'check_device_error: try_capture_a_frame returned None')
@@ -768,7 +768,7 @@ class MainWindow(FluentWindow):
768
768
  show_info_bar(self.window(), message, title=self.tr('Success'))
769
769
  else:
770
770
  from ok.ui.qt.util.Alert import alert_error
771
- alert_error(f"Import failed: {message}")
771
+ alert_error(self.tr("Import failed: {error}").format(error=message))
772
772
  except Exception as e:
773
773
  logger.error(f'Error importing .okscript file: {e}')
774
774
 
@@ -263,6 +263,10 @@
263
263
  <source>Reloaded {count} tasks</source>
264
264
  <translation>Reloaded {count} tasks</translation>
265
265
  </message>
266
+ <message>
267
+ <source>The app is controlled by {owner}</source>
268
+ <translation>The app is controlled by {owner}</translation>
269
+ </message>
266
270
  </context>
267
271
  <context>
268
272
  <name>GlobalConfigCard</name>
@@ -479,6 +483,10 @@
479
483
  <source>Run Code</source>
480
484
  <translation>Run Code</translation>
481
485
  </message>
486
+ <message>
487
+ <source>Import failed: {error}</source>
488
+ <translation>Import failed: {error}</translation>
489
+ </message>
482
490
  </context>
483
491
  <context>
484
492
  <name>MessageWindow</name>
@@ -728,6 +736,14 @@
728
736
  <source>Pause All</source>
729
737
  <translation>Pause All</translation>
730
738
  </message>
739
+ <message>
740
+ <source>Error</source>
741
+ <translation>Error</translation>
742
+ </message>
743
+ <message>
744
+ <source>No Task to Run, Please Enable Task First!</source>
745
+ <translation>No Task to Run, Please Enable Task First!</translation>
746
+ </message>
731
747
  </context>
732
748
  <context>
733
749
  <name>StartCard</name>
@@ -980,6 +996,10 @@
980
996
  <source>View Log</source>
981
997
  <translation>View Log</translation>
982
998
  </message>
999
+ <message>
1000
+ <source>Please Start First</source>
1001
+ <translation>Please Start First</translation>
1002
+ </message>
983
1003
  </context>
984
1004
  <context>
985
1005
  <name>TaskButtons</name>
@@ -1802,6 +1822,86 @@
1802
1822
  <source>Allow local coding agents to control this app and run Python code</source>
1803
1823
  <translation>Allow local coding agents to control this app and run Python code</translation>
1804
1824
  </message>
1825
+ <message>
1826
+ <source>PC version requires admin privileges, Please restart this app with admin privileges!</source>
1827
+ <translation>PC version requires admin privileges, Please restart this app with admin privileges!</translation>
1828
+ </message>
1829
+ <message>
1830
+ <source>No game selected!</source>
1831
+ <translation>No game selected!</translation>
1832
+ </message>
1833
+ <message>
1834
+ <source>Capture failed, please check game window</source>
1835
+ <translation>Capture failed, please check game window</translation>
1836
+ </message>
1837
+ <message>
1838
+ <source>Game path does not exist, Please open game manually!</source>
1839
+ <translation>Game path does not exist, Please open game manually!</translation>
1840
+ </message>
1841
+ <message>
1842
+ <source>Start game timeout!</source>
1843
+ <translation>Start game timeout!</translation>
1844
+ </message>
1845
+ <message>
1846
+ <source>Window is minimized or out of screen, and don't use full-screen exclusive mode!</source>
1847
+ <translation>Window is minimized or out of screen, and don't use full-screen exclusive mode!</translation>
1848
+ </message>
1849
+ <message>
1850
+ <source>Start game failed, please start game first</source>
1851
+ <translation>Start game failed, please start game first</translation>
1852
+ </message>
1853
+ <message>
1854
+ <source>{} is not connected, please select the game window.</source>
1855
+ <translation>{} is not connected, please select the game window.</translation>
1856
+ </message>
1857
+ <message>
1858
+ <source>Selected capture method is not supported by the game or your system!</source>
1859
+ <translation>Selected capture method is not supported by the game or your system!</translation>
1860
+ </message>
1861
+ <message>
1862
+ <source>Image resource load failed, please try install again.(Don't put the app in Downloads folder)</source>
1863
+ <translation>Image resource load failed, please try install again.(Don't put the app in Downloads folder)</translation>
1864
+ </message>
1865
+ <message>
1866
+ <source>Emulator is not connected, start the emulator first!</source>
1867
+ <translation>Emulator is not connected, start the emulator first!</translation>
1868
+ </message>
1869
+ <message>
1870
+ <source>Can't start game, make sure the game is installed</source>
1871
+ <translation>Can't start game, make sure the game is installed</translation>
1872
+ </message>
1873
+ <message>
1874
+ <source>NPU inferring Error, you might need to update the Intel NPU driver!</source>
1875
+ <translation>NPU inferring Error, you might need to update the Intel NPU driver!</translation>
1876
+ </message>
1877
+ <message>
1878
+ <source>Export failed</source>
1879
+ <translation>Export failed</translation>
1880
+ </message>
1881
+ <message>
1882
+ <source>Cannot start: the app is controlled by {owner}</source>
1883
+ <translation>Cannot start: the app is controlled by {owner}</translation>
1884
+ </message>
1885
+ <message>
1886
+ <source>Cannot start {name}: the app is controlled by {owner}</source>
1887
+ <translation>Cannot start {name}: the app is controlled by {owner}</translation>
1888
+ </message>
1889
+ <message>
1890
+ <source>Start failed: {error}</source>
1891
+ <translation>Start failed: {error}</translation>
1892
+ </message>
1893
+ <message>
1894
+ <source>Windows Graphics Capture is busy</source>
1895
+ <translation>Windows Graphics Capture is busy</translation>
1896
+ </message>
1897
+ <message>
1898
+ <source>Windows Graphics Capture is not supported on this system.</source>
1899
+ <translation>Windows Graphics Capture is not supported on this system.</translation>
1900
+ </message>
1901
+ <message>
1902
+ <source>Paused because browser exited</source>
1903
+ <translation>Paused because browser exited</translation>
1904
+ </message>
1805
1905
  </context>
1806
1906
  <context>
1807
1907
  <name>ScheduleTaskTable</name>
@@ -2807,6 +2907,18 @@
2807
2907
  <source>Guide</source>
2808
2908
  <translation>Guide</translation>
2809
2909
  </message>
2910
+ <message>
2911
+ <source>Error deleting task: {error}</source>
2912
+ <translation>Error deleting task: {error}</translation>
2913
+ </message>
2914
+ <message>
2915
+ <source>Error creating task: {error}</source>
2916
+ <translation>Error creating task: {error}</translation>
2917
+ </message>
2918
+ <message>
2919
+ <source>Error copying task: {error}</source>
2920
+ <translation>Error copying task: {error}</translation>
2921
+ </message>
2810
2922
  </context>
2811
2923
  <context>
2812
2924
  <name>CreateTaskDialog</name>
@@ -2968,6 +3080,22 @@
2968
3080
  <source>Compress (obsolete)</source>
2969
3081
  <translation>Compress (obsolete)</translation>
2970
3082
  </message>
3083
+ <message>
3084
+ <source>Screenshot failed: {e}</source>
3085
+ <translation>Screenshot failed: {e}</translation>
3086
+ </message>
3087
+ <message>
3088
+ <source>Save failed: {e}</source>
3089
+ <translation>Save failed: {e}</translation>
3090
+ </message>
3091
+ <message>
3092
+ <source>Delete failed: {e}</source>
3093
+ <translation>Delete failed: {e}</translation>
3094
+ </message>
3095
+ <message>
3096
+ <source>Could not write screenshot to {path}</source>
3097
+ <translation>Could not write screenshot to {path}</translation>
3098
+ </message>
2971
3099
  </context>
2972
3100
  <context>
2973
3101
  <name>TemplateInputDialog</name>
@@ -2979,6 +3107,10 @@
2979
3107
  <source>Cancel</source>
2980
3108
  <translation>Cancel</translation>
2981
3109
  </message>
3110
+ <message>
3111
+ <source>Parameter '{param_name}' is required!</source>
3112
+ <translation>Parameter '{param_name}' is required!</translation>
3113
+ </message>
2982
3114
  </context>
2983
3115
  <context>
2984
3116
  <name>SelectInteractionListView</name>
@@ -3278,6 +3410,14 @@
3278
3410
  <source>Backup cleanup pending. Restart to retry.</source>
3279
3411
  <translation>Backup cleanup pending. Restart to retry.</translation>
3280
3412
  </message>
3413
+ <message>
3414
+ <source>The release archive belongs to a different plugin</source>
3415
+ <translation>The release archive belongs to a different plugin</translation>
3416
+ </message>
3417
+ <message>
3418
+ <source>The release archive is not a newer plugin version</source>
3419
+ <translation>The release archive is not a newer plugin version</translation>
3420
+ </message>
3281
3421
  </context>
3282
3422
  <context>
3283
3423
  <name>LabelAndMcpServer</name>
@@ -3302,4 +3442,15 @@
3302
3442
  <translation>No</translation>
3303
3443
  </message>
3304
3444
  </context>
3445
+ <context>
3446
+ <name>JobControls</name>
3447
+ <message>
3448
+ <source>The app is controlled by {owner}</source>
3449
+ <translation>The app is controlled by {owner}</translation>
3450
+ </message>
3451
+ <message>
3452
+ <source>Failed after {seconds}s</source>
3453
+ <translation>Failed after {seconds}s</translation>
3454
+ </message>
3455
+ </context>
3305
3456
  </TS>
@@ -272,6 +272,10 @@
272
272
  <source>Reloaded {count} tasks</source>
273
273
  <translation>Se han recargado {count} tareas</translation>
274
274
  </message>
275
+ <message>
276
+ <source>The app is controlled by {owner}</source>
277
+ <translation>{owner} está controlando la aplicación</translation>
278
+ </message>
275
279
  </context>
276
280
  <context>
277
281
  <name>GlobalConfigCard</name>
@@ -489,6 +493,10 @@
489
493
  <source>Run Code</source>
490
494
  <translation>Ejecutar código</translation>
491
495
  </message>
496
+ <message>
497
+ <source>Import failed: {error}</source>
498
+ <translation>Error al importar: {error}</translation>
499
+ </message>
492
500
  </context>
493
501
  <context>
494
502
  <name>MessageWindow</name>
@@ -726,6 +734,14 @@
726
734
  <source>Pause All</source>
727
735
  <translation>Pausar todo</translation>
728
736
  </message>
737
+ <message>
738
+ <source>Error</source>
739
+ <translation>Error</translation>
740
+ </message>
741
+ <message>
742
+ <source>No Task to Run, Please Enable Task First!</source>
743
+ <translation>No hay tareas para ejecutar. ¡Active una tarea primero!</translation>
744
+ </message>
729
745
  </context>
730
746
  <context>
731
747
  <name>StartCard</name>
@@ -978,6 +994,10 @@
978
994
  <source>View Log</source>
979
995
  <translation>Ver registro</translation>
980
996
  </message>
997
+ <message>
998
+ <source>Please Start First</source>
999
+ <translation>Inicie primero</translation>
1000
+ </message>
981
1001
  </context>
982
1002
  <context>
983
1003
  <name>TaskButtons</name>
@@ -1800,6 +1820,86 @@
1800
1820
  <source>Allow local coding agents to control this app and run Python code</source>
1801
1821
  <translation>Permitir que los agentes de programación locales controlen esta aplicación y ejecuten código Python</translation>
1802
1822
  </message>
1823
+ <message>
1824
+ <source>PC version requires admin privileges, Please restart this app with admin privileges!</source>
1825
+ <translation>La versión de PC requiere privilegios de administrador, ¡por favor, reinicia esta aplicación con privilegios de administrador!</translation>
1826
+ </message>
1827
+ <message>
1828
+ <source>No game selected!</source>
1829
+ <translation>¡No se ha seleccionado ningún juego!</translation>
1830
+ </message>
1831
+ <message>
1832
+ <source>Capture failed, please check game window</source>
1833
+ <translation>Captura fallida, por favor, comprueba la ventana del juego</translation>
1834
+ </message>
1835
+ <message>
1836
+ <source>Game path does not exist, Please open game manually!</source>
1837
+ <translation>La ruta del juego no existe, ¡por favor, abre el juego manualmente!</translation>
1838
+ </message>
1839
+ <message>
1840
+ <source>Start game timeout!</source>
1841
+ <translation>¡Tiempo de inicio del juego agotado!</translation>
1842
+ </message>
1843
+ <message>
1844
+ <source>Window is minimized or out of screen, and don't use full-screen exclusive mode!</source>
1845
+ <translation>La ventana está minimizada o fuera de la pantalla, ¡y no uses el modo de pantalla completa exclusiva!</translation>
1846
+ </message>
1847
+ <message>
1848
+ <source>Start game failed, please start game first</source>
1849
+ <translation>Error al iniciar el juego, por favor, inicia el juego primero</translation>
1850
+ </message>
1851
+ <message>
1852
+ <source>{} is not connected, please select the game window.</source>
1853
+ <translation>{} no está conectada, por favor, selecciona la ventana del juego y el método de captura.</translation>
1854
+ </message>
1855
+ <message>
1856
+ <source>Selected capture method is not supported by the game or your system!</source>
1857
+ <translation>¡El método de captura seleccionado no es compatible con el juego o tu sistema!</translation>
1858
+ </message>
1859
+ <message>
1860
+ <source>Image resource load failed, please try install again.(Don't put the app in Downloads folder)</source>
1861
+ <translation>Falló la carga del recurso de imagen, por favor, intenta instalar de nuevo. (No pongas la aplicación en la carpeta de Descargas)</translation>
1862
+ </message>
1863
+ <message>
1864
+ <source>Emulator is not connected, start the emulator first!</source>
1865
+ <translation>El emulador no está conectado, ¡inicia el emulador primero!</translation>
1866
+ </message>
1867
+ <message>
1868
+ <source>Can't start game, make sure the game is installed</source>
1869
+ <translation>No se puede iniciar el juego, asegúrate de que el juego está instalado</translation>
1870
+ </message>
1871
+ <message>
1872
+ <source>NPU inferring Error, you might need to update the Intel NPU driver!</source>
1873
+ <translation>¡Error de inferencia de la NPU, es posible que necesite actualizar el controlador de la NPU de Intel!</translation>
1874
+ </message>
1875
+ <message>
1876
+ <source>Export failed</source>
1877
+ <translation>Error al exportar</translation>
1878
+ </message>
1879
+ <message>
1880
+ <source>Cannot start: the app is controlled by {owner}</source>
1881
+ <translation>No se puede iniciar: {owner} está controlando la aplicación</translation>
1882
+ </message>
1883
+ <message>
1884
+ <source>Cannot start {name}: the app is controlled by {owner}</source>
1885
+ <translation>No se puede iniciar {name}: {owner} está controlando la aplicación</translation>
1886
+ </message>
1887
+ <message>
1888
+ <source>Start failed: {error}</source>
1889
+ <translation>Error al iniciar: {error}</translation>
1890
+ </message>
1891
+ <message>
1892
+ <source>Windows Graphics Capture is busy</source>
1893
+ <translation>Windows Graphics Capture está ocupado</translation>
1894
+ </message>
1895
+ <message>
1896
+ <source>Windows Graphics Capture is not supported on this system.</source>
1897
+ <translation>Este sistema no admite Windows Graphics Capture.</translation>
1898
+ </message>
1899
+ <message>
1900
+ <source>Paused because browser exited</source>
1901
+ <translation>En pausa porque se cerró el navegador</translation>
1902
+ </message>
1803
1903
  </context>
1804
1904
  <context>
1805
1905
  <name>ScheduleTaskTable</name>
@@ -2805,6 +2905,18 @@
2805
2905
  <source>Guide</source>
2806
2906
  <translation>Guía</translation>
2807
2907
  </message>
2908
+ <message>
2909
+ <source>Error deleting task: {error}</source>
2910
+ <translation>Error al eliminar la tarea: {error}</translation>
2911
+ </message>
2912
+ <message>
2913
+ <source>Error creating task: {error}</source>
2914
+ <translation>Error al crear la tarea: {error}</translation>
2915
+ </message>
2916
+ <message>
2917
+ <source>Error copying task: {error}</source>
2918
+ <translation>Error al copiar la tarea: {error}</translation>
2919
+ </message>
2808
2920
  </context>
2809
2921
  <context>
2810
2922
  <name>CreateTaskDialog</name>
@@ -2966,6 +3078,22 @@
2966
3078
  <source>Compress (obsolete)</source>
2967
3079
  <translation>Comprimir (obsoleto)</translation>
2968
3080
  </message>
3081
+ <message>
3082
+ <source>Screenshot failed: {e}</source>
3083
+ <translation>Error al capturar la pantalla: {e}</translation>
3084
+ </message>
3085
+ <message>
3086
+ <source>Save failed: {e}</source>
3087
+ <translation>Error al guardar: {e}</translation>
3088
+ </message>
3089
+ <message>
3090
+ <source>Delete failed: {e}</source>
3091
+ <translation>Error al eliminar: {e}</translation>
3092
+ </message>
3093
+ <message>
3094
+ <source>Could not write screenshot to {path}</source>
3095
+ <translation>No se pudo guardar la captura de pantalla en {path}</translation>
3096
+ </message>
2969
3097
  </context>
2970
3098
  <context>
2971
3099
  <name>TemplateInputDialog</name>
@@ -2977,6 +3105,10 @@
2977
3105
  <source>Cancel</source>
2978
3106
  <translation>Cancelar</translation>
2979
3107
  </message>
3108
+ <message>
3109
+ <source>Parameter '{param_name}' is required!</source>
3110
+ <translation>¡El parámetro «{param_name}» es obligatorio!</translation>
3111
+ </message>
2980
3112
  </context>
2981
3113
  <context>
2982
3114
  <name>SelectInteractionListView</name>
@@ -3276,6 +3408,14 @@
3276
3408
  <source>Backup cleanup pending. Restart to retry.</source>
3277
3409
  <translation>Limpieza de copias pendiente. Reinicia para reintentar.</translation>
3278
3410
  </message>
3411
+ <message>
3412
+ <source>The release archive belongs to a different plugin</source>
3413
+ <translation>El archivo de la versión pertenece a otro complemento</translation>
3414
+ </message>
3415
+ <message>
3416
+ <source>The release archive is not a newer plugin version</source>
3417
+ <translation>El archivo de la versión no contiene una versión más reciente del complemento</translation>
3418
+ </message>
3279
3419
  </context>
3280
3420
  <context>
3281
3421
  <name>LabelAndMcpServer</name>
@@ -3300,4 +3440,15 @@
3300
3440
  <translation>No</translation>
3301
3441
  </message>
3302
3442
  </context>
3443
+ <context>
3444
+ <name>JobControls</name>
3445
+ <message>
3446
+ <source>The app is controlled by {owner}</source>
3447
+ <translation>{owner} está controlando la aplicación</translation>
3448
+ </message>
3449
+ <message>
3450
+ <source>Failed after {seconds}s</source>
3451
+ <translation>Error tras {seconds} s</translation>
3452
+ </message>
3453
+ </context>
3303
3454
  </TS>