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.
- {ok_script-2.0.20 → ok_script-2.0.22}/PKG-INFO +1 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/docs/mcp.md +10 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/code_runner.py +1 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/mcp_runner.py +66 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/mcp_server.py +4 -2
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/start_controller.py +4 -4
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/MainWindow.py +1 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/en_US.qm +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/en_US.ts +151 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/es_ES.qm +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/es_ES.ts +151 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ja_JP.qm +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ja_JP.ts +151 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ko_KR.qm +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/ko_KR.ts +151 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_CN.qm +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_CN.ts +151 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_TW.qm +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/zh_TW.ts +151 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/plugins/PluginTab.py +2 -2
- ok_script-2.0.22/ok/ui/qt/resources.py +19088 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/EditTaskTab.py +6 -6
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/StartButton.py +1 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TemplateFactory.py +1 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TemplateTab.py +3 -2
- {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/PKG-INFO +1 -1
- {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/SOURCES.txt +1 -0
- ok_script-2.0.22/tests/test_mcp_cleanup.py +166 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mcp_server.py +35 -0
- ok_script-2.0.22/tests/test_translation_fallback.py +222 -0
- ok_script-2.0.20/ok/ui/qt/resources.py +0 -17921
- ok_script-2.0.20/tests/test_translation_fallback.py +0 -119
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/develop/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/develop/agents/openai.yaml +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/develop/references/windows-input.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/generate-templates/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/reload-tasks/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/reload-tasks/agents/openai.yaml +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-env/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-env/agents/openai.yaml +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-env/assets/ok-script-develop/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-project/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/setup-project/agents/openai.yaml +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/use_venv/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/write-test/SKILL.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/.agents/skills/write-test/agents/openai.yaml +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/LICENSE.txt +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/MANIFEST.in +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/README.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/diagnostics/qq_trace.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/docs/agent-setup.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/docs/feature-crops.md +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/examples/mcp_observe.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/__main__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/emulator_base.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/emulator_windows.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/platform_windows.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/alas/utils.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/assets/default-icon.png +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/deep.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/minitouch.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/nemu_ipc.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/nemu_utils.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/pool.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/timer.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/adb/util.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/windows/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/windows/d3d11.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/capture/windows/dump.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/cli.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/capture_labels.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/config_schema.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/downloads.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/events.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/icons.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/notifications.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/plugin_staging.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/plugins.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/screenshot.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/script_editing.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/script_packager.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/script_templates.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/skills.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/task_manager.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/template_store.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/translation.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/core/ui_config.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/DeviceManager.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/adb.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/base.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/bitblt.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/bitblt_utils.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/browser.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/desktop_duplication.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/hwnd_window.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/image.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/nemu_ipc.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/types.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/update.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/windows_graphics.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/capture_methods/windows_graphics_hdr.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/adb.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/base.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/browser.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/do_nothing.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/foreground_post_message.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/genshin.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/keys.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/post_message.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/pydirect.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/pynput.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/interaction_methods/swipe.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/device/intercation.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/Box.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/Feature.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/FeatureSet.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/feature/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/gui/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/gui/util/pyappify_startup.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/manager.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/messenger_images.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/pipeline.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/ppocr.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/providers.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/system.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/notification/windows_messenger.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ocr/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ocr/download_paddle_model.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Media/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Security/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/Storage/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/UI/ViewManagement/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/UI/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/Windows/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/delegate.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/export.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/idldsl.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/inspectable.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/roapi.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/types.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/rotypes/winstring.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/DiagnosisTask.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/TaskExecutor.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/exceptions.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/task/task.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/OKTestRunner.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/RunTests.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/TaskTestCase.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/test/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/third_party/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/third_party/paperclip.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/overlay/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/overlay/win32_gdi.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/Communicate.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/MessageWindow.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/StartController.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/TabTitles.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/AboutTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/HttpTextEdit.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/LinksBar.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/ProjectCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/UpdateCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/VersionCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/about/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/OKIcon.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/accent_color.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/config.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/design_system.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/icons.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/common/style_sheet.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/DebugTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/JobControls.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/OverlayWidget.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/RunCodeTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/Screenshot.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/debug/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/events.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/GettextTranslator.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/path.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/i18n/update.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/overlay/OverlayWindow.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/overlay/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/plugins/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/plugins/imported_tabs.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/card.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/discord.svg +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/heart.svg +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/message_window.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/setting_interface.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/status_bar.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/stop.svg +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/dark/tab.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/card.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/discord.svg +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/heart.svg +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/message_window.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/setting_interface.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/status_bar.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/stop.svg +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qss/light/tab.qss +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/qt.qrc +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/GlobalConfigCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/GlobalConfigTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/SettingTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/settings/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/LogWindow.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/SelectCaptureListView.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/SelectInteractionListView.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/StartCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/StartTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/start/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ConfigCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ConfigItemFactory.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ConfigLabelAndWidget.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndButtons.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndDoubleSpinBox.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndDropDown.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndFileSelector.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndGlobal.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndLineEdit.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndList.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndMcpServer.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndMultiSelection.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndSpinBox.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndSwitchButton.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndTextEdit.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/LabelAndWidget.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/MarkUpWindow.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ModifyListDialog.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ModifyListItem.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/OneTimeTaskTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/PythonHighlighter.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/RecordScript.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ScheduleTaskTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/ScriptPackager.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskManger.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskOpButton.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TaskTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TooltipTableWidget.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/TriggerTaskTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/tasks/schedule_index_sync.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/Alert.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/InitWorker.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/app.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/download.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/pip_util.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/pyappify_startup.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/touch_scroll.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/util/windows_thumbnail.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/BaseLoading.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/BaseWindow.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/Card.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/CustomTab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/EmptyCard.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ExpandCardLayout.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/FlowLayout.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/FramelessDialog.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ImageWidget.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ImportWarningDialog.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/ListTableWidgetItem.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/NumericTableWidgetItem.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/OkCompactSpinBox.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/SortingTableWidgetItem.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/StartLoadingDialog.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/StatusBar.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/Tab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/TabWidget.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/UpdateConfigWidgetItem.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/WidgetWithVLabel.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/YesNonWidgetItem.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/ui/qt/widget/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/update/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/update/copy_ok_folder.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/update/inline_ok_requirements.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/Analytics.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/GlobalConfig.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/__init__.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/blur.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/clazz.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/collection.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/color.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/config.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/explorer.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/file.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/gpu_driver_settings.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/handler.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/i18n.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/logger.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/partial_sync_repo.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/print_hwnd.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/process.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/version.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/window.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok/util/windows_schedule.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/dependency_links.txt +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/entry_points.txt +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/not-zip-safe +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/requires.txt +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/ok_script.egg-info/top_level.txt +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/pyproject.toml +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/setup.cfg +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/setup.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_accent_color.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_app.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_base_interaction.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_blur.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_box.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_capture_update.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_cli.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_config_card.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_core_events.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_core_ui_services.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_debug_job_controls.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_device_manager.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_executor_jobs.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_expand_card_layout.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_explorer.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_global_config.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_gpu_driver_settings.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_handler.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_headless_imports.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_inline_ok_requirements.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_logger.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_main_window_notifications.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_main_window_startup_tab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_main_window_system_theme.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mcp_runner.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mcp_setting.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_missing_frame.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_mouse_buttons.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_navigation_state.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_nemu_ipc_capture.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_notifications.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_ok_mutex.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_overlay_custom_draw.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_overlay_lifecycle.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_package_metadata.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_plugin_staging.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_plugin_tabs.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_plugins.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_process.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_process_mutex.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_pyappify_startup_update.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_qt_events.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_qt_legacy_imports.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_qt_page_layout.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_runtime_startup.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_schedule_startup.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_schedule_task_index_sync.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_screenshot_naming.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_screenshot_rendering.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_skills.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_start_controller.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_start_tab_overlay.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_executor_next_frame.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_executor_queue.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_reloading.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_task_ui.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_template_compression.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_template_generation.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_template_tab.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_touch_scroll.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_ui_config.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_version.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_graphics_capture.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_graphics_hdr.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_schedule_target_parse.py +0 -0
- {ok_script-2.0.20 → ok_script-2.0.22}/tests/test_windows_schedule_xml.py +0 -0
|
@@ -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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
|
|
Binary file
|
|
@@ -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>
|
|
Binary file
|
|
@@ -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>
|
|
Binary file
|