PyBreeze 1.0.32__tar.gz → 1.0.34__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 (283) hide show
  1. {pybreeze-1.0.32 → pybreeze-1.0.34}/PKG-INFO +122 -36
  2. {pybreeze-1.0.32 → pybreeze-1.0.34}/README.md +120 -34
  3. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/__init__.py +10 -7
  4. pybreeze-1.0.34/pybreeze/extend/language_server/__init__.py +6 -0
  5. pybreeze-1.0.34/pybreeze/extend/language_server/__main__.py +17 -0
  6. pybreeze-1.0.34/pybreeze/extend/language_server/launch.py +42 -0
  7. pybreeze-1.0.34/pybreeze/extend/language_server/server_main.py +59 -0
  8. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/mail_thunder_extend/mail_thunder_setting.py +40 -11
  9. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/process_executor/file_runner_process.py +16 -12
  10. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/process_executor/process_executor_utils.py +24 -12
  11. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/process_executor/prthinker/prthinker_process.py +5 -5
  12. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/process_executor/python_task_process_manager.py +19 -14
  13. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/process_executor/queue_pump.py +0 -5
  14. pybreeze-1.0.34/pybreeze/extend/process_executor/run_notice.py +27 -0
  15. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/process_executor/test_pioneer/test_pioneer_process_manager.py +2 -1
  16. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/prthinker_extend/prthinker_setting.py +21 -13
  17. pybreeze-1.0.34/pybreeze/extend_multi_language/english_integrations.py +165 -0
  18. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend_multi_language/extend_english.py +192 -100
  19. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend_multi_language/extend_traditional_chinese.py +235 -175
  20. pybreeze-1.0.34/pybreeze/extend_multi_language/supported_languages.py +88 -0
  21. pybreeze-1.0.34/pybreeze/extend_multi_language/traditional_chinese_error_text.py +115 -0
  22. pybreeze-1.0.34/pybreeze/extend_multi_language/traditional_chinese_integrations.py +162 -0
  23. pybreeze-1.0.34/pybreeze/extend_multi_language/update_language_dict.py +36 -0
  24. pybreeze-1.0.34/pybreeze/pybreeze_ui/busy_cursor.py +29 -0
  25. pybreeze-1.0.34/pybreeze/pybreeze_ui/code_result_logs.py +31 -0
  26. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/ssh/sftp_session.py +2 -2
  27. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_command_widget.py +221 -36
  28. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_connect_thread.py +5 -0
  29. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_file_viewer_widget.py +46 -14
  30. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_host_key_policy.py +36 -2
  31. pybreeze-1.0.34/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_key_loader.py +149 -0
  32. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_login_widget.py +15 -3
  33. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/url/ai_code_review_gui.py +12 -1
  34. pybreeze-1.0.34/pybreeze/pybreeze_ui/design/flow_layout.py +101 -0
  35. pybreeze-1.0.34/pybreeze/pybreeze_ui/design/panels.py +78 -0
  36. pybreeze-1.0.34/pybreeze/pybreeze_ui/design/tokens.py +117 -0
  37. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_editor_widget.py +55 -36
  38. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_items.py +65 -61
  39. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_mermaid_parser.py +305 -68
  40. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_scene.py +12 -13
  41. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_view.py +41 -8
  42. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/dialog/prthinker_setting_dialog.py +33 -7
  43. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/editor_main/file_tree_context_menu.py +68 -14
  44. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/editor_main/main_ui.py +122 -9
  45. pybreeze-1.0.34/pybreeze/pybreeze_ui/editor_main/pybreeze_icon.ico +0 -0
  46. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_code_review_gui.py +28 -10
  47. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/global_rule.py +4 -21
  48. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_editor_widget.py +12 -7
  49. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/skills/skills_send_gui.py +11 -9
  50. pybreeze-1.0.34/pybreeze/pybreeze_ui/fixed_pitch.py +40 -0
  51. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_thread.py +113 -61
  52. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_widget.py +14 -9
  53. pybreeze-1.0.34/pybreeze/pybreeze_ui/jupyter_lab_gui/lab_page.py +62 -0
  54. pybreeze-1.0.34/pybreeze/pybreeze_ui/mcp_gui/mcp_client_gui.py +411 -0
  55. pybreeze-1.0.34/pybreeze/pybreeze_ui/mcp_gui/mcp_panels.py +290 -0
  56. pybreeze-1.0.34/pybreeze/pybreeze_ui/mcp_gui/mcp_profile_dialog.py +176 -0
  57. pybreeze-1.0.34/pybreeze/pybreeze_ui/mcp_gui/mcp_server_panel.py +175 -0
  58. pybreeze-1.0.34/pybreeze/pybreeze_ui/mcp_gui/mcp_worker.py +41 -0
  59. pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/build_api_testka_menu.py +35 -0
  60. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/build_autocontrol_menu.py +27 -20
  61. pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/build_automation_file_menu.py +25 -0
  62. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/automation_menu/automation_menu_factory.py +44 -12
  63. pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/build_load_density_menu.py +36 -0
  64. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/build_mail_thunder_menu.py +2 -3
  65. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/build_test_pioneer_menu.py +8 -1
  66. pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/build_webrunner_menu.py +25 -0
  67. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu/jupyter_lab_tab.py +6 -2
  68. pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/build_automation_install_menu.py +74 -0
  69. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/menu_utils.py +6 -3
  70. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/plugin_menu/build_plugin_menu.py +9 -8
  71. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/plugin_menu/build_run_with_menu.py +20 -5
  72. pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/tools/tools_menu.py +271 -0
  73. pybreeze-1.0.34/pybreeze/pybreeze_ui/navigation/navigation_dock.py +128 -0
  74. pybreeze-1.0.34/pybreeze/pybreeze_ui/navigation/navigation_model.py +151 -0
  75. pybreeze-1.0.34/pybreeze/pybreeze_ui/report_gui/report_viewer_gui.py +394 -0
  76. pybreeze-1.0.34/pybreeze/pybreeze_ui/run_shortcut.py +37 -0
  77. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/show_code_window/code_window.py +40 -24
  78. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/syntax/syntax_extend.py +9 -3
  79. pybreeze-1.0.34/pybreeze/pybreeze_ui/terminal_view.py +85 -0
  80. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/thread_keeper.py +30 -0
  81. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/curl_import_gui.py +41 -16
  82. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/diff_gui.py +45 -2
  83. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/har_import_gui.py +36 -13
  84. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/hash_gui.py +4 -2
  85. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/header_analyzer_gui.py +47 -5
  86. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/http_status_gui.py +20 -3
  87. pybreeze-1.0.34/pybreeze/pybreeze_ui/tools_gui/import_gaps.py +48 -0
  88. pybreeze-1.0.34/pybreeze/pybreeze_ui/tools_gui/json_editor_gui.py +398 -0
  89. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/json_format_gui.py +10 -2
  90. pybreeze-1.0.34/pybreeze/pybreeze_ui/tools_gui/json_tree_panel.py +338 -0
  91. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/jwt_decoder_gui.py +7 -2
  92. pybreeze-1.0.34/pybreeze/pybreeze_ui/tools_gui/keyword_reference_gui.py +272 -0
  93. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/output_actions.py +1 -1
  94. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/query_json_gui.py +15 -2
  95. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/regex_gui.py +6 -4
  96. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/response_inspector_gui.py +17 -12
  97. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/timestamp_gui.py +6 -5
  98. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/url_builder_gui.py +15 -2
  99. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/curl_import/curl_parser.py +76 -18
  100. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/curl_import/request_body.py +48 -8
  101. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/curl_import/script_templates.py +1 -33
  102. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/diff_tools/text_diff.py +18 -12
  103. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/exception/exception_tags.py +55 -0
  104. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/exception/exceptions.py +16 -0
  105. pybreeze-1.0.34/pybreeze/utils/execution_report/html_report.py +125 -0
  106. pybreeze-1.0.34/pybreeze/utils/execution_report/junit_xml.py +176 -0
  107. pybreeze-1.0.34/pybreeze/utils/execution_report/record_reports.py +208 -0
  108. pybreeze-1.0.34/pybreeze/utils/execution_report/report_files.py +165 -0
  109. pybreeze-1.0.34/pybreeze/utils/execution_report/report_filter.py +106 -0
  110. pybreeze-1.0.34/pybreeze/utils/execution_report/report_schema.py +373 -0
  111. pybreeze-1.0.34/pybreeze/utils/execution_report/safe_xml.py +136 -0
  112. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/har_import/har_codegen.py +7 -36
  113. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/har_import/har_parser.py +2 -2
  114. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/header_tools/header_analyzer.py +117 -32
  115. pybreeze-1.0.34/pybreeze/utils/header_tools/header_rules.py +179 -0
  116. pybreeze-1.0.34/pybreeze/utils/header_tools/header_sarif.py +191 -0
  117. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/http_reference/status_codes.py +42 -8
  118. pybreeze-1.0.34/pybreeze/utils/import_targets/builtin_targets.py +69 -0
  119. pybreeze-1.0.34/pybreeze/utils/import_targets/normalized_request.py +119 -0
  120. pybreeze-1.0.34/pybreeze/utils/import_targets/target_registry.py +156 -0
  121. pybreeze-1.0.34/pybreeze/utils/import_targets/webrunner_target.py +79 -0
  122. pybreeze-1.0.34/pybreeze/utils/json_format/json_document.py +262 -0
  123. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/json_format/json_process.py +6 -6
  124. pybreeze-1.0.34/pybreeze/utils/json_format/json_tree_edit.py +300 -0
  125. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/jwt_tools/jwt_decoder.py +26 -1
  126. pybreeze-1.0.34/pybreeze/utils/language_service/action_adapter.py +343 -0
  127. pybreeze-1.0.34/pybreeze/utils/language_service/framework_profiles.py +55 -0
  128. pybreeze-1.0.34/pybreeze/utils/language_service/json_scan.py +274 -0
  129. pybreeze-1.0.34/pybreeze/utils/language_service/keyword_metadata.py +223 -0
  130. pybreeze-1.0.34/pybreeze/utils/language_service/lsp_server.py +431 -0
  131. pybreeze-1.0.34/pybreeze/utils/language_service/metadata_probe.py +163 -0
  132. pybreeze-1.0.34/pybreeze/utils/language_service/service_adapter.py +271 -0
  133. pybreeze-1.0.34/pybreeze/utils/mcp/mcp_call_log.py +113 -0
  134. pybreeze-1.0.34/pybreeze/utils/mcp/mcp_client.py +414 -0
  135. pybreeze-1.0.34/pybreeze/utils/mcp/mcp_profile.py +184 -0
  136. pybreeze-1.0.34/pybreeze/utils/mcp/mcp_redaction.py +76 -0
  137. pybreeze-1.0.34/pybreeze/utils/mcp/mcp_transport.py +155 -0
  138. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/network/public_http.py +3 -2
  139. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/network/url_validation.py +10 -11
  140. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/regex_tools/regex_tester.py +3 -3
  141. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/subprocess_util.py +20 -5
  142. pybreeze-1.0.34/pybreeze/utils/terminal_style.py +178 -0
  143. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/terminal_text.py +26 -5
  144. pybreeze-1.0.34/pybreeze/utils/timestamp_tools/__init__.py +0 -0
  145. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/timestamp_tools/timestamp_converter.py +73 -11
  146. pybreeze-1.0.34/pybreeze/utils/ui_state.py +48 -0
  147. pybreeze-1.0.34/pybreeze/utils/url_tools/__init__.py +0 -0
  148. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze.egg-info/PKG-INFO +122 -36
  149. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze.egg-info/SOURCES.txt +68 -12
  150. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze.egg-info/requires.txt +1 -1
  151. {pybreeze-1.0.32 → pybreeze-1.0.34}/pyproject.toml +6 -2
  152. pybreeze-1.0.32/pybreeze/extend/process_executor/api_testka/api_testka_process.py +0 -42
  153. pybreeze-1.0.32/pybreeze/extend/process_executor/auto_control/auto_control_process.py +0 -42
  154. pybreeze-1.0.32/pybreeze/extend/process_executor/file_automation/file_automation_process.py +0 -42
  155. pybreeze-1.0.32/pybreeze/extend/process_executor/load_density/load_density_process.py +0 -42
  156. pybreeze-1.0.32/pybreeze/extend/process_executor/mail_thunder/mail_thunder_process.py +0 -16
  157. pybreeze-1.0.32/pybreeze/extend/process_executor/web_runner/web_runner_process.py +0 -42
  158. pybreeze-1.0.32/pybreeze/extend_multi_language/update_language_dict.py +0 -29
  159. pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_key_loader.py +0 -85
  160. pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/build_api_testka_menu.py +0 -42
  161. pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/build_automation_file_menu.py +0 -39
  162. pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/build_load_density_menu.py +0 -43
  163. pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/build_webrunner_menu.py +0 -39
  164. pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/build_automation_install_menu.py +0 -124
  165. pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/tools/tools_menu.py +0 -286
  166. {pybreeze-1.0.32 → pybreeze-1.0.34}/LICENSE +0 -0
  167. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/__main__.py +0 -0
  168. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/__init__.py +0 -0
  169. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/mail_thunder_extend/__init__.py +0 -0
  170. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/extend/process_executor/__init__.py +0 -0
  171. {pybreeze-1.0.32/pybreeze/extend/process_executor/api_testka → pybreeze-1.0.34/pybreeze/extend/process_executor/prthinker}/__init__.py +0 -0
  172. {pybreeze-1.0.32/pybreeze/extend/process_executor/auto_control → pybreeze-1.0.34/pybreeze/extend/process_executor/test_pioneer}/__init__.py +0 -0
  173. {pybreeze-1.0.32/pybreeze/extend/process_executor/file_automation → pybreeze-1.0.34/pybreeze/extend/prthinker_extend}/__init__.py +0 -0
  174. {pybreeze-1.0.32/pybreeze/extend/process_executor/load_density → pybreeze-1.0.34/pybreeze/extend_multi_language}/__init__.py +0 -0
  175. {pybreeze-1.0.32/pybreeze/extend/process_executor/mail_thunder → pybreeze-1.0.34/pybreeze/pybreeze_ui}/__init__.py +0 -0
  176. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/closing.py +0 -0
  177. {pybreeze-1.0.32/pybreeze/extend/process_executor/prthinker → pybreeze-1.0.34/pybreeze/pybreeze_ui/connect_gui}/__init__.py +0 -0
  178. {pybreeze-1.0.32/pybreeze/extend/process_executor/test_pioneer → pybreeze-1.0.34/pybreeze/pybreeze_ui/connect_gui/ssh}/__init__.py +0 -0
  179. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_main_widget.py +0 -0
  180. {pybreeze-1.0.32/pybreeze/extend/process_executor/web_runner → pybreeze-1.0.34/pybreeze/pybreeze_ui/connect_gui/url}/__init__.py +0 -0
  181. {pybreeze-1.0.32/pybreeze/extend/prthinker_extend → pybreeze-1.0.34/pybreeze/pybreeze_ui/design}/__init__.py +0 -0
  182. {pybreeze-1.0.32/pybreeze/extend_multi_language → pybreeze-1.0.34/pybreeze/pybreeze_ui/diagram_editor}/__init__.py +0 -0
  183. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_commands.py +0 -0
  184. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_net_utils.py +0 -0
  185. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/diagram_editor/diagram_property_panel.py +0 -0
  186. {pybreeze-1.0.32/pybreeze/pybreeze_ui → pybreeze-1.0.34/pybreeze/pybreeze_ui/dialog}/__init__.py +0 -0
  187. {pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui → pybreeze-1.0.34/pybreeze/pybreeze_ui/editor_main}/__init__.py +0 -0
  188. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/error_text.py +0 -0
  189. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/exact_text.py +0 -0
  190. {pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh → pybreeze-1.0.34/pybreeze/pybreeze_ui/extend_ai_gui}/__init__.py +0 -0
  191. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/ai_gui_global_variable.py +0 -0
  192. {pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/url → pybreeze-1.0.34/pybreeze/pybreeze_ui/extend_ai_gui/code_review}/__init__.py +0 -0
  193. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/code_review_thread.py +0 -0
  194. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_chain.py +0 -0
  195. {pybreeze-1.0.32/pybreeze/pybreeze_ui/diagram_editor → pybreeze-1.0.34/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui}/__init__.py +0 -0
  196. {pybreeze-1.0.32/pybreeze/pybreeze_ui/dialog → pybreeze-1.0.34/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates}/__init__.py +0 -0
  197. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/code_smell_detector.py +0 -0
  198. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_code_review.py +0 -0
  199. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_summary_prompt.py +0 -0
  200. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge.py +0 -0
  201. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge_single_review.py +0 -0
  202. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/linter.py +0 -0
  203. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/step_by_step_analysis.py +0 -0
  204. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/total_summary.py +0 -0
  205. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_prompt_editor_widget.py +0 -0
  206. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_file_io.py +0 -0
  207. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_editor_widget.py +0 -0
  208. {pybreeze-1.0.32/pybreeze/pybreeze_ui/editor_main → pybreeze-1.0.34/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates}/__init__.py +0 -0
  209. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_explainer.py +0 -0
  210. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_review.py +0 -0
  211. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_store.py +0 -0
  212. {pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui → pybreeze-1.0.34/pybreeze/pybreeze_ui/extend_ai_gui/skills}/__init__.py +0 -0
  213. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/gui_thread_gc.py +0 -0
  214. {pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui/code_review → pybreeze-1.0.34/pybreeze/pybreeze_ui/jupyter_lab_gui}/__init__.py +0 -0
  215. {pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui → pybreeze-1.0.34/pybreeze/pybreeze_ui/mcp_gui}/__init__.py +0 -0
  216. {pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu}/__init__.py +0 -0
  217. {pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu}/__init__.py +0 -0
  218. {pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui/skills → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu}/__init__.py +0 -0
  219. {pybreeze-1.0.32/pybreeze/pybreeze_ui/jupyter_lab_gui → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu}/__init__.py +0 -0
  220. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu}/__init__.py +0 -0
  221. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu}/__init__.py +0 -0
  222. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu}/__init__.py +0 -0
  223. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/prthinker_menu}/__init__.py +0 -0
  224. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/automation_menu/prthinker_menu/build_prthinker_menu.py +0 -0
  225. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu}/__init__.py +0 -0
  226. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu}/__init__.py +0 -0
  227. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/build_menubar.py +0 -0
  228. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu}/__init__.py +0 -0
  229. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/prthinker_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/install_menu}/__init__.py +0 -0
  230. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/install_menu/automation_menu}/__init__.py +0 -0
  231. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/install_menu/install_utils.py +0 -0
  232. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/install_menu/tools_menu}/__init__.py +0 -0
  233. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/menu/install_menu/tools_menu/build_tool_install_menu.py +0 -0
  234. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/plugin_menu}/__init__.py +0 -0
  235. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/install_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/menu/tools}/__init__.py +0 -0
  236. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/install_menu/automation_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/navigation}/__init__.py +0 -0
  237. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/plain_text.py +0 -0
  238. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/install_menu/tools_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/report_gui}/__init__.py +0 -0
  239. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/plugin_menu → pybreeze-1.0.34/pybreeze/pybreeze_ui/show_code_window}/__init__.py +0 -0
  240. {pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/tools → pybreeze-1.0.34/pybreeze/pybreeze_ui/syntax}/__init__.py +0 -0
  241. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/syntax/syntax_keyword.py +0 -0
  242. {pybreeze-1.0.32/pybreeze/pybreeze_ui/show_code_window → pybreeze-1.0.34/pybreeze/pybreeze_ui/tools_gui}/__init__.py +0 -0
  243. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/pybreeze_ui/tools_gui/tool_tabs.py +0 -0
  244. {pybreeze-1.0.32/pybreeze/pybreeze_ui/syntax → pybreeze-1.0.34/pybreeze/utils}/__init__.py +0 -0
  245. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/app_dirs.py +0 -0
  246. {pybreeze-1.0.32/pybreeze/pybreeze_ui/tools_gui → pybreeze-1.0.34/pybreeze/utils/curl_import}/__init__.py +0 -0
  247. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/curl_import/request_codegen.py +0 -0
  248. {pybreeze-1.0.32/pybreeze/utils → pybreeze-1.0.34/pybreeze/utils/diff_tools}/__init__.py +0 -0
  249. {pybreeze-1.0.32/pybreeze/utils/curl_import → pybreeze-1.0.34/pybreeze/utils/exception}/__init__.py +0 -0
  250. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/exception/error_templates.py +0 -0
  251. {pybreeze-1.0.32/pybreeze/utils/diff_tools → pybreeze-1.0.34/pybreeze/utils/execution_report}/__init__.py +0 -0
  252. {pybreeze-1.0.32/pybreeze/utils/exception → pybreeze-1.0.34/pybreeze/utils/file_process}/__init__.py +0 -0
  253. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/file_process/get_dir_file_list.py +0 -0
  254. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/file_process/read_capped.py +0 -0
  255. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/file_process/replace_file.py +0 -0
  256. {pybreeze-1.0.32/pybreeze/utils/file_process → pybreeze-1.0.34/pybreeze/utils/har_import}/__init__.py +0 -0
  257. {pybreeze-1.0.32/pybreeze/utils/har_import → pybreeze-1.0.34/pybreeze/utils/hash_tools}/__init__.py +0 -0
  258. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/hash_tools/hash_text.py +0 -0
  259. {pybreeze-1.0.32/pybreeze/utils/hash_tools → pybreeze-1.0.34/pybreeze/utils/header_tools}/__init__.py +0 -0
  260. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/header_tools/header_merge.py +0 -0
  261. {pybreeze-1.0.32/pybreeze/utils/header_tools → pybreeze-1.0.34/pybreeze/utils/http_reference}/__init__.py +0 -0
  262. {pybreeze-1.0.32/pybreeze/utils/http_reference → pybreeze-1.0.34/pybreeze/utils/import_targets}/__init__.py +0 -0
  263. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/json_format/__init__.py +0 -0
  264. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/json_format/view_safe.py +0 -0
  265. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/jwt_tools/__init__.py +0 -0
  266. {pybreeze-1.0.32/pybreeze/utils/logging → pybreeze-1.0.34/pybreeze/utils/language_service}/__init__.py +0 -0
  267. {pybreeze-1.0.32/pybreeze/utils/manager → pybreeze-1.0.34/pybreeze/utils/logging}/__init__.py +0 -0
  268. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/logging/logger.py +0 -0
  269. {pybreeze-1.0.32/pybreeze/utils/manager/package_manager → pybreeze-1.0.34/pybreeze/utils/manager}/__init__.py +0 -0
  270. {pybreeze-1.0.32/pybreeze/utils/network → pybreeze-1.0.34/pybreeze/utils/manager/package_manager}/__init__.py +0 -0
  271. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/manager/package_manager/package_manager_class.py +0 -0
  272. {pybreeze-1.0.32/pybreeze/utils/query_tools → pybreeze-1.0.34/pybreeze/utils/mcp}/__init__.py +0 -0
  273. {pybreeze-1.0.32/pybreeze/utils/regex_tools → pybreeze-1.0.34/pybreeze/utils/network}/__init__.py +0 -0
  274. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/network/http_client.py +0 -0
  275. {pybreeze-1.0.32/pybreeze/utils/response_inspector → pybreeze-1.0.34/pybreeze/utils/query_tools}/__init__.py +0 -0
  276. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/query_tools/query_convert.py +0 -0
  277. {pybreeze-1.0.32/pybreeze/utils/timestamp_tools → pybreeze-1.0.34/pybreeze/utils/regex_tools}/__init__.py +0 -0
  278. {pybreeze-1.0.32/pybreeze/utils/url_tools → pybreeze-1.0.34/pybreeze/utils/response_inspector}/__init__.py +0 -0
  279. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/response_inspector/response_analyzer.py +0 -0
  280. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze/utils/url_tools/url_convert.py +0 -0
  281. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze.egg-info/dependency_links.txt +0 -0
  282. {pybreeze-1.0.32 → pybreeze-1.0.34}/pybreeze.egg-info/top_level.txt +0 -0
  283. {pybreeze-1.0.32 → pybreeze-1.0.34}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybreeze
3
- Version: 1.0.32
3
+ Version: 1.0.34
4
4
  Summary: IDE for multi automation
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Integration-Automation/PyBreeze
@@ -24,7 +24,7 @@ Requires-Dist: je_web_runner
24
24
  Requires-Dist: je_load_density
25
25
  Requires-Dist: je_api_testka
26
26
  Requires-Dist: je-mail-thunder
27
- Requires-Dist: automation-file
27
+ Requires-Dist: automation-file[all]
28
28
  Requires-Dist: PySide6==6.11.2
29
29
  Requires-Dist: test_pioneer
30
30
  Requires-Dist: paramiko
@@ -33,7 +33,7 @@ Dynamic: license-file
33
33
 
34
34
  # PyBreeze: The Automation-First IDE
35
35
 
36
- [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
36
+ [![Python 3.10–3.14](https://img.shields.io/badge/python-3.10--3.14-blue.svg)](https://www.python.org/downloads/)
37
37
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
38
38
  [![PySide6](https://img.shields.io/badge/GUI-PySide6-green.svg)](https://doc.qt.io/qtforpython/)
39
39
  [![Documentation](https://readthedocs.org/projects/pybreeze/badge/?version=latest)](https://pybreeze.readthedocs.io/en/latest/index.html)
@@ -44,7 +44,7 @@ Dynamic: license-file
44
44
 
45
45
  ![PyBreeze main window](images/main_window.png)
46
46
 
47
- *The main window: automation keywords highlighted in an APITestka action file, project tree on the left, run/format/debug/terminal panes below.*
47
+ *The main window: an APITestka action file open in the editor, project tree on the left, run/format/debug/terminal panes below.*
48
48
 
49
49
  ---
50
50
 
@@ -105,26 +105,30 @@ Each module gets the same menu shape: **Run** (single script, batch directory, w
105
105
 
106
106
  ### IDE core
107
107
 
108
- - **Automation-aware syntax highlighting** — the `AT_*` / GUI / Web / Load keyword sets are registered for `.json`, and TestPioneer's schema for `.yml` and `.yaml`, on top of JEditor's language support
109
- - **Code editor** — built on [JEditor](https://github.com/Integration-Automation/JEDITOR): tabs, project tree, format checker, debugger, terminal, variable inspector and a git client pane
110
- - **Script execution** — single or batch, each run in a window of its own with a Stop button; action files are passed by path, and a script from the tab in front that is too long for a Windows command line (~32 KB) goes through a temporary file
108
+ - **Automation keyword sets** — the `AT_*` / GUI / Web / Load keyword sets are registered for `.json`, and TestPioneer's schema for `.yml` and `.yaml`, on top of JEditor's language support. JEditor does not colour them yet: it highlights those files with its own rules for the suffix, which leave registered keywords out
109
+ - **Code editor** — built on [JEditor](https://github.com/Integration-Automation/JEDITOR): tabs, project tree, format checker, debugger, terminal and a git client pane
110
+ - **Navigation panel** — a dock at the left lists what the menus hold as one tree (Automation, Tools, Settings): type in its box to find a tool or a command by name, then press Enter or double-click to open it. **Dock ▸ Navigation** shows and hides it, and a panel closed on purpose stays closed at the next start
111
+ - **Fits a small screen** — a tool tab never asks for more than 60 font heights of width: a row of buttons too long for the tab wraps onto the next line instead of pushing the window wider than the display
112
+ - **Script execution** — single or batch, each run in a window of its own with a Stop button (Run ▸ Stop All Program stops them all), which asks whether to stop the run when it is closed while the run goes on; action files are passed by path, and a script from the tab in front that is too long for a Windows command line (~32 KB) goes through a temporary file
111
113
  - **Report generation** — HTML / JSON / XML after a run, with optional email delivery
112
- - **Integrated JupyterLab** — launches as a tab, installing JupyterLab into the project venv if it is missing
113
- - **Virtual environment awareness** — `venv/` and `.venv/` are detected and used automatically; without one, scripts run on the interpreter the IDE runs on
114
+ - **Integrated JupyterLab** — launches as a tab, in the same interpreter a run would use, installing JupyterLab there if it is missing, and upgrading it and its server first when either is a release with a known vulnerability (JupyterLab before 4.5.10 or 4.6.0–4.6.1, jupyter_server before 2.20.0); the tab stays on the lab, and a link to anywhere else opens in your browser
115
+ - **Virtual environment awareness** — a run uses the interpreter chosen under **Python Env**; with none chosen, a `venv/` or `.venv/` in the working folder is detected and used, and without one, the interpreter the IDE runs on
114
116
 
115
117
  ---
116
118
 
117
119
  ## Built-in Tools
118
120
 
121
+ In a tool with one main button, Ctrl+Enter anywhere in it presses that button: its text boxes take Enter as a new line. In Query ↔ JSON and the URL parser/builder, which convert both ways, it goes the way the input reads: from JSON when the input is a JSON object.
122
+
119
123
  ### cURL Import — a copied request becomes a runnable script
120
124
 
121
- Paste a `curl` command from your browser's dev tools and pick a target. The parser handles method, URL, headers, bodies, basic auth, `-G` query parameters, `-F` multipart fields (uploads become `files=open(...)`), the `--json` shortcut, `-d @file` bodies and multi-line continuations. Repeated `-H` values are combined the way HTTP combines them (`; ` for cookies, `, ` otherwise) instead of the last one silently winning. Nothing is ever executed — it is pure parsing.
125
+ Paste a `curl` command from your browser's dev tools and pick a target. The parser handles method, URL, headers, bodies, basic auth, `-G` and `--url-query` query parameters, `-F` multipart fields (uploads become `files=open(...)`), the `--json` shortcut, `-d @file` bodies and multi-line continuations. Every other curl option that takes a value has it consumed, so it is never mistaken for the URL, and an `--expand-` option is read as the one it expands, its `{{variables}}` kept as written. Repeated `-H` values are combined the way HTTP combines them (`; ` for cookies, `, ` otherwise) instead of the last one silently winning. A browser's `Accept-Encoding` that accepts `br`, `zstd` or `*` is left out of the generated code, so `requests` asks only for what it can decode (with it, a server answering in zstd left a script with only `requests` installed printing compressed bytes). The method is the one curl sends: POST for a body and HEAD for `-I`, unless `-X` names one (`-X GET -d ...` stays a GET with a body). Nothing is ever executed — it is pure parsing.
122
126
 
123
127
  | Target: pytest | Target: APITestka JSON action |
124
128
  |---|---|
125
129
  | ![cURL import to pytest](images/tool_curl_import.png) | ![cURL import to APITestka action](images/tool_curl_import_action.png) |
126
130
 
127
- Targets: Python `requests`, a ready-to-run **pytest** test, **APITestka** (Python or a `[["AT_test_api_method", {...}]]` action list that `execute_files` runs directly), and a **LoadDensity** Locust load test. Copy the output, open it straight into an editor tab, or save it with the right extension. One click also hands the parsed URL to the URL parser/builder or the headers to the header analyzer.
131
+ Targets: Python `requests`, a ready-to-run **pytest** test, **APITestka** (Python or a `[["AT_test_api_method", {...}]]` action list that `execute_files` runs directly), a **LoadDensity** Locust load test, and a **WebRunner** action list that visits the address in a browser. A target that cannot send everything a request holds says so under the output ("Not sent by this target: headers · the body"): a LoadDensity run drives a method and a URL, and a browser visit keeps the URL, the cookies and a time limit. Copy the output, open it straight into an editor tab, or save it with the right extension. One click also hands the parsed URL to the URL parser/builder or the headers to the header analyzer.
128
132
 
129
133
  ### HAR Import — a whole session becomes a test suite
130
134
 
@@ -144,13 +148,74 @@ The status code is looked up in the HTTP reference, headers are parsed, a JSON b
144
148
 
145
149
  ![Header Analyzer](images/tool_header_analyzer.png)
146
150
 
147
- Reports names sent more than once, `Set-Cookie` entries missing `Secure` / `HttpOnly` / `SameSite`, wildcard CORS (and the wildcard-plus-credentials combination browsers reject outright), an HSTS `max-age` too short to survive a restart, CSP `unsafe-inline` / `unsafe-eval`, product banners, deprecated headers, and — for responses — the security headers that are absent. Headers carrying credentials are reported **by name only**; their values never enter the report.
151
+ Reports names sent more than once, `Set-Cookie` entries missing `Secure` / `HttpOnly` / `SameSite` and those a browser drops outright (a `__Secure-` / `__Host-` name whose rules are broken, `SameSite=None` without `Secure`), wildcard CORS (and the wildcard-plus-credentials combination browsers reject outright), an HSTS `max-age` too short to survive a restart, CSP `unsafe-inline` / `unsafe-eval`, product banners, headers current browsers ignore (`X-XSS-Protection` other than `0`, `Expect-CT`, `Public-Key-Pins`, `P3P`, the old prefixed CSP names), and — for responses — the security headers that are absent, counting a CSP `frame-ancestors` directive as `X-Frame-Options`, as the OWASP HTTP Headers Cheat Sheet does. Headers carrying credentials are reported **by name only**; their values never enter the report.
152
+
153
+ **Export findings as SARIF** saves the analysis as a SARIF 2.1.0 file that GitHub Code Scanning and other security tooling read: each finding with its rule, level, line, what to do about it and a link. The same export runs without the IDE, for CI:
154
+
155
+ ```bash
156
+ python -m pybreeze.utils.header_tools.header_sarif response-headers.txt -o headers.sarif
157
+ ```
158
+
159
+ `-` reads the headers from standard input, leaving out `-o` writes to standard output, and `--fail-on-warning` exits with 1 when a finding is a warning. The report names rules and lines and quotes no header value.
148
160
 
149
161
  ### Text Diff
150
162
 
151
163
  ![Text Diff](images/tool_diff.png)
152
164
 
153
- Compare two payloads — an expected vs. actual API response, say — and get a unified diff plus a one-line added/removed summary.
165
+ Compare two payloads — an expected vs. actual API response, say — and get a unified diff, its added and removed lines in the theme's colours, plus a one-line added/removed summary.
166
+
167
+ ### Report Viewer
168
+
169
+ **Tools → Report Viewer Tab** opens what a run produced, whatever ran it, into one view.
170
+
171
+ - **Reads** the automation packages' own reports (APITestka, AutoControl, WebRunner, LoadDensity: the `<name>_success.json` / `<name>_failure.json` pair or the `.xml` pair; open either and the other is read with it), **JUnit XML** (pytest's `--junitxml`, and most other runners), and reports exported from PyBreeze. What a file is, is told from what it holds.
172
+ - **Shows** each run as a tree with how every result ended and how long it took; the selected result's details and error, its output, what it left behind, and the package's own record of it, untouched.
173
+ - **Filters** all open runs together: by ending (passed, failed, error, skipped), by time taken, by package, and by text in a name or an error. A line under the tree counts what is shown.
174
+ - **Exports** a run as an execution report (JSON), as **JUnit XML** for a CI service's test summary, or as one self-contained **HTML page** for people, which can be opened here again.
175
+ - The **MCP Client**'s Calls page opens its session here with **Open in Report Viewer**.
176
+
177
+ A report is a file from somewhere: it is read as data (XML that declares a document type is refused), everything in it is shown as text, and the paths it names are listed, not opened.
178
+
179
+ ### MCP Client
180
+
181
+ **Tools → MCP Client Tab** connects to [Model Context Protocol](https://modelcontextprotocol.io) servers and shows what each offers: **tools** to call, **resources** to read, **prompts** to fill in.
182
+
183
+ - **Servers** are set up once and kept for you (`~/.pybreeze/mcp_servers.json`, readable by you alone): a name, the command that starts the server (one argument a line, never a shell line), its environment variables, and how long a request may take. The file uses the `mcpServers` layout other clients write, so a list made elsewhere can be dropped in.
184
+ - **A call is asked about first**: the tool, the server and the arguments as they will be sent, with No as the default. Tick *Do not ask again* to trust one tool of one server. What a server says of its own tool ("changes nothing") is shown, not relied on.
185
+ - **A server that comes with a project** (`.mcp.json` in the project folder) is listed, never started by itself: connecting to it shows its command and asks.
186
+ - **Cancel** gives up a call on its way; a server that does not answer within its time limit is given up on; one that goes away is said so, with the last line of its own log. **Connect** again to start over.
187
+ - **Calls** lists the session: when, which tool, how it ended, how long it took. **Export Session...** saves it as an execution report (JSON).
188
+
189
+ Put keys and tokens in the server's environment variables, not in its command: their values are shown as dots, and are taken out of the log, of error messages and of exported sessions wherever they turn up. Servers are started as local programs (the protocol's standard-input-and-output transport).
190
+
191
+ ### Keywords for action scripts
192
+
193
+ A WebRunner, AutoControl or LoadDensity script is a JSON list of actions, `["keyword"]` or `["keyword", arguments]`. Open one (`.json`) in the editor and it is completed and checked against the keywords of the framework **as it is installed**:
194
+
195
+ - **Completion** — the framework's keywords where an action's name goes, a keyword's parameters where an argument's name goes.
196
+ - **Diagnostics** — a keyword that version does not have (with the nearest one suggested), a parameter the keyword does not take, a required one left out, a list of values of the wrong length, an action of the wrong shape, and text that is not JSON. In the IDE's language.
197
+ - **Hover** and **go to definition** — a keyword's signature and documentation, and the line of the package that defines it.
198
+
199
+ Nothing about a keyword is kept in PyBreeze. Each framework is asked, in a process of its own, by the interpreter that runs your scripts (the one chosen in the IDE, a `.venv` in the project, else the IDE's own), so upgrading a framework changes what is offered. A framework that is missing or fails to import costs its own keywords and nothing else.
200
+
201
+ **Tools → Automation Keywords Tab** shows the same keywords: each framework's version, what the editor offers for it, every keyword with its parameters and documentation, a filter, and **Copy as Action**. When a framework gives none, it says why.
202
+
203
+ The editor gets all this from a language server, which any editor that speaks the Language Server Protocol can start too:
204
+
205
+ ```bash
206
+ python -m pybreeze.extend.language_server [--interpreter /path/to/python] [--language Traditional_Chinese]
207
+ ```
208
+
209
+ ### JSON Editor
210
+
211
+ Edit a JSON file as a **Tree** or as **Text** (**Tools → JSON Editor Tab**). Both are views of one document, so they cannot disagree.
212
+
213
+ - **Tree** — add, delete, move up or down, and rename in place; type over a value, or give it another type (object, array, string, number, boolean, null). A number is kept as it is written: `1.0` stays `1.0`.
214
+ - **Text** — the JSON itself, always there. It is checked as you type and a line under the views says where it stops being JSON; the tree waits until it is JSON again, and nothing typed is thrown away.
215
+ - **Undo / Redo** step through the document whichever view changed it, and a tab with unsaved changes asks before it closes or opens another file.
216
+ - A file is written back the way it was found: its indent (spaces or tabs), on one line if it was, with its final line break. Alignment by hand and blank lines are not kept by an edit in the tree.
217
+
218
+ It is a JSON editor, not a second code editor: a file is opened into it from its **Open...** button.
154
219
 
155
220
  ### The everyday utilities
156
221
 
@@ -158,14 +223,14 @@ Each is a tab or a dock, each has the same copy / open-in-editor / save-to-file
158
223
 
159
224
  ![JWT decoder, regex tester, HTTP status reference, JSON format](images/tools_montage_a.png)
160
225
 
161
- - **JWT Decoder** — header and payload as pretty JSON, with `exp` / `iat` / `nbf` / `auth_time` as readable UTC. Inspection only: the signature is never verified and the token is never trusted.
226
+ - **JWT Decoder** — header and payload as pretty JSON, with `exp` / `iat` / `nbf` / `auth_time` as readable UTC. Inspection only: the signature is never verified and the token is never trusted. An encrypted token (JWE, five parts) is named as one: its claims need the recipient's key.
162
227
  - **Regex Tester** — `IGNORECASE` / `MULTILINE` / `DOTALL` / `VERBOSE`, every match with offsets, numbered groups and named groups. Enter in the pattern runs it. An invalid pattern reports a friendly error instead of crashing.
163
- - **HTTP Status Reference** — search the full status table (sourced from the standard library, so it stays current) by code prefix or keyword.
228
+ - **HTTP Status Reference** — search the full status table (from the standard library, in the words RFC 9110 and Python 3.14 give on every supported Python) by code prefix or keyword; a status is also found by the name RFC 9110 replaced (`Unprocessable Entity`).
164
229
  - **JSON Format** — pretty-print or minify, with a clear validation error when the input is not JSON.
165
230
 
166
231
  ![Timestamp converter, hash generator, query/JSON, URL builder](images/tools_montage_b.png)
167
232
 
168
- - **Timestamp Converter** — a Unix epoch (seconds, milliseconds, microseconds or nanoseconds, auto-detected) or an ISO-8601 date-time (with `Z`, `+08`, `+0800` or `+08:00`, any number of fraction digits, basic or extended) in, every representation out in UTC. Deterministic and independent of the local time zone.
233
+ - **Timestamp Converter** — a Unix epoch (seconds, milliseconds, microseconds or nanoseconds, auto-detected) or an ISO-8601 date-time (with `Z`, `+08`, `+0800` or `+08:00`, any number of fraction digits, basic or extended, and an RFC 9557 zone after the offset as Java's `ZonedDateTime` writes it: `+01:00[Europe/Paris]`) or an HTTP date (`Sun, 06 Nov 1994 08:49:37 GMT`, as in `Date` or `Last-Modified`, and the two older forms RFC 9110 accepts) in, every representation out in UTC. Deterministic and independent of the local time zone.
169
234
  - **Hash Generator** — SHA-256, SHA-512, SHA-1 and MD5 at once (MD5/SHA-1 for interoperability with `usedforsecurity=False`, never for security decisions).
170
235
  - **Query ⇄ JSON** — `application/x-www-form-urlencoded` to pretty JSON and back; repeated keys become arrays and vice versa.
171
236
  - **URL Parser / Builder** — scheme, host, port, path, query, fragment and credentials as an editable JSON object, and back again. Brackets IPv6 literals and re-encodes query parameters for you.
@@ -176,29 +241,31 @@ Each is a tab or a dock, each has the same copy / open-in-editor / save-to-file
176
241
 
177
242
  *A Mermaid `flowchart` pasted into the importer and laid out automatically.*
178
243
 
179
- A WYSIWYG `QGraphicsScene` editor: rectangle, rounded, ellipse and diamond nodes, bezier connections with edge labels, free text and images. Mermaid `flowchart` / `graph` import runs a Sugiyama-style layout (layering, crossing reduction, cross-axis alignment). Save and open as `.diagram.json`, export to PNG or SVG, with undo/redo, align, distribute, grid, snap and zoom. Images fetched from a URL are SSRF-validated and size-capped.
244
+ A WYSIWYG `QGraphicsScene` editor: rectangle, rounded, ellipse and diamond nodes, bezier connections with edge labels, free text and images. Mermaid `flowchart` / `graph` import reads labels as Mermaid shows them (`<br>` line breaks, `#quot;` / `#9829;` entity codes, markdown strings as plain text), takes Mermaid 11's named shapes (`A@{ shape: circle }`) as the nearest of the four, and runs a Sugiyama-style layout (layering, crossing reduction, cross-axis alignment). Save and open as `.diagram.json`, export to PNG or SVG, with undo/redo, align, distribute, grid, snap and zoom. Images fetched from a URL are SSRF-validated and size-capped.
180
245
 
181
246
  ### SSH Client — terminal and remote file tree side by side
182
247
 
183
248
  ![SSH client](images/ssh_client.png)
184
249
 
185
- Password or private-key authentication (the key file picked with Browse, starting in `~/.ssh`), an interactive shell with ANSI handling and keepalive, and a lazy-loading SFTP tree with create-folder / rename / delete / upload / download. Every SFTP request runs in the background, so a stalled link never freezes the IDE. An upload asks before it replaces a file on the server, and a transfer can be cancelled from the tree's menu. Both directions write to a temporary file first, so a dropped link leaves the old copy whole. Unknown host keys are **not** auto-accepted: the SHA256 fingerprint is shown for confirmation on first connection (trust on first use) and persisted to `~/.pybreeze/ssh_known_hosts`.
250
+ Password or private-key authentication (the key file picked with Browse, starting in `~/.ssh`: an RSA, Ed25519 or ECDSA key in OpenSSH or PEM format, PKCS#8 included; a PuTTY `.ppk` key is exported from PuTTYgen as an OpenSSH key first, as the error message says; with key authentication the password field reads Passphrase and takes the key's passphrase), an interactive shell with keepalive that shows ANSI colours, in a fixed-pitch font, whose width and height the shell is told as the view is resized (Up and Down bring back earlier commands, Enter on an empty line reaches the shell, `clear` and `reset` wipe the view, and **Interrupt**, or Ctrl+C in the command line with nothing selected, stops what runs in it; the view shows output line by line, so programs that draw on the whole screen by moving the cursor, such as `vim` or `htop`, come out garbled), and a lazy-loading SFTP tree with create-folder / rename / delete / upload / download (F2 renames and Delete deletes the entry in focus, as in the project tree). Every SFTP request runs in the background, so a stalled link never freezes the IDE. An upload asks before it replaces a file on the server, and a transfer can be cancelled from the tree's menu. Both directions write to a temporary file first, so a dropped link leaves the old copy whole. Unknown host keys are **not** auto-accepted: the SHA256 fingerprint is shown for confirmation on first connection (trust on first use) and persisted to `~/.pybreeze/ssh_known_hosts`; hosts in `~/.ssh/known_hosts` are trusted as well. A host trusted before that shows another key is refused without a question, naming both SHA256 fingerprints and the file to remove its line from if the key was changed on purpose.
186
251
 
187
252
  ### And also
188
253
 
189
- - **File Tree Context Menu** — right-click to create, rename, delete, copy absolute or relative paths, or reveal the item in your platform file manager (a file shown selected in Explorer and Finder). Renaming or deleting a file open in an editor tab keeps the tab in sync.
254
+ - **File Tree Context Menu** — right-click to create, rename, delete, copy absolute or relative paths, or reveal the item in your platform file manager (a file shown selected in Explorer and Finder). F2 renames and Delete deletes the item in focus while the tree has the focus. A delete asks first, with No as the default, and moves the item to the trash (the Recycle Bin on Windows); where there is none, as on some network drives, it asks again before deleting for good. Renaming or deleting a file open in an editor tab keeps the tab in sync.
190
255
  - **Package Manager** — install automation modules and build tools from the menu, output in a run window.
191
- - **Integrated Documentation** — each module's docs and GitHub page open as in-IDE browser tabs.
256
+ - **Integrated Documentation** — each module's docs and GitHub page open as in-IDE browser tabs (TestPioneer's documentation is its GitHub README).
192
257
 
193
258
  ---
194
259
 
195
260
  ## AI-Assisted Development
196
261
 
262
+ As in the tools, Ctrl+Enter in AI Code Review, CoT Code Review or Skill Send presses its send button.
263
+
197
264
  ### AI Code Review
198
265
 
199
266
  ![AI code review client](images/ai_code_review.png)
200
267
 
201
- *Shown in the pre-send state.* Send a selection to an LLM endpoint, then accept or reject the suggestion — the tally is kept in `~/.pybreeze/response_stats.txt`. The URL is SSRF-validated, the connection goes only to the address that was checked, redirects are not followed, and the response body is size-capped before it reaches the panel.
268
+ *Shown in the pre-send state.* Send a selection to an LLM endpoint (as the form field `code` in the body of a POST, the default, or a PUT; GET and DELETE send the URL alone), then accept or reject the suggestion — the tally is kept in `~/.pybreeze/response_stats.txt`. The URL is SSRF-validated, the connection goes only to the address that was checked, redirects are not followed, and the response body is size-capped before it reaches the panel. An endpoint on this machine or on a private network, such as a local model server, is therefore refused; CoT Code Review and Skill Send check their endpoint URL the same way.
202
269
 
203
270
  ### Chain-of-Thought Code Review (prthinker)
204
271
 
@@ -206,7 +273,7 @@ Run the [prthinker](https://github.com/JE-Chen/Code-Review-Framework-Combining-L
206
273
 
207
274
  ![prthinker settings](images/prthinker_setting.png)
208
275
 
209
- One settings form holds the inference backend (`remote`, `local`, OpenAI-compatible, Anthropic, Gemini, Cohere, Mistral, `claude-cli`, `codex-cli`), the code host (GitHub / GitLab / Gitea) and the repository. **Keys and tokens are handed to the review as environment variables, never on a command line** where a process list would show them — and they are masked in logs. The model name goes to whichever backend is chosen. Rule retrieval (RAG) is `off` unless set to `remote`, which asks the prthinker server's `/rag`: prthinker's local rule index ships with its repository, not with the package installed from it. The review runs with the interpreter chosen in `Python Env`, so PyBreeze itself can stay on an older Python than the 3.12 prthinker needs.
276
+ One settings form holds the inference backend (`remote`, `local`, OpenAI-compatible, Anthropic, Gemini, Cohere, Mistral, `claude-cli`, `codex-cli`), the code host (GitHub / GitLab / Gitea) and the repository. **Keys and tokens are handed to the review as environment variables, never on a command line** where a process list would show them — and they are masked in logs. The model name goes to whichever backend is chosen. Gemini, Cohere and Mistral have no key field: chosen, the form names the variable prthinker reads their key from (`PRTHINKER_GEMINI_API_KEY`, `PRTHINKER_COHERE_API_KEY`, `PRTHINKER_MISTRAL_API_KEY`), which is set before PyBreeze starts. Rule retrieval (RAG) is `off` unless set to `remote`, which asks the prthinker server's `/rag`: prthinker's local rule index ships with its repository, not with the package installed from it. The review runs with the interpreter chosen in `Python Env`, so PyBreeze itself can stay on an older Python than the 3.12 prthinker needs.
210
277
 
211
278
  ### CoT Prompt Editor
212
279
 
@@ -214,7 +281,7 @@ One settings form holds the inference backend (`remote`, `local`, OpenAI-compati
214
281
 
215
282
  Create and manage the multi-step review chain: first summary → first code review → a judge of that review → linter → code smell detector → step-by-step analysis → total summary → a judge of the summary. Each step quotes the answers it needs from the steps before it. Files are watched, so an external edit shows up immediately.
216
283
 
217
- Run the chain from **Tools → AI → CoT Code Review** (a tab, or a dock from the Dock menu): paste the code, give the endpoint URL, and each step's answer appears in the selector as it arrives.
284
+ Run the chain from **Tools → AI → CoT Code Review** (a tab, or a dock from the Dock menu): paste the code, give the endpoint URL, and each step's answer appears in the selector as it arrives. Each step is a POST of the JSON `{"prompt": "..."}`, and the response body, as text, is that step's answer.
218
285
 
219
286
  ### Skill Prompt Editor & Skill Send
220
287
 
@@ -222,7 +289,7 @@ Run the chain from **Tools → AI → CoT Code Review** (a tab, or a dock from t
222
289
  |---|---|
223
290
  | ![Skill prompt editor](images/skill_prompt_editor.png) | ![Skill send](images/skills_send.png) |
224
291
 
225
- Define reusable skill prompts (code explanation, code review), then pick one, edit it if needed, and send it to an LLM endpoint from a dedicated tab or dock. *Both shown in the pre-send state — no endpoint was contacted for these screenshots.*
292
+ Define reusable skill prompts (code explanation, code review), then pick one, edit it if needed, and send it to an LLM endpoint from a dedicated tab or dock: a POST of the JSON `{"code": "..."}` holding the prompt, whose response body is shown as it is. *Both shown in the pre-send state — no endpoint was contacted for these screenshots.*
226
293
 
227
294
  ---
228
295
 
@@ -230,10 +297,10 @@ Define reusable skill prompts (code explanation, code review), then pick one, ed
230
297
 
231
298
  PyBreeze inherits JEditor's plugin architecture, auto-discovered from a `jeditor_plugins/` directory in the working directory. A plugin can register:
232
299
 
233
- - **Syntax highlighting** — keyword sets and rules for any language
300
+ - **Syntax highlighting** — keyword sets and rules for a file suffix JEditor does not colour itself (for `.c`, `.cpp`, `.go`, `.java`, `.js`, `.json`, `.rs`, `.sh`, `.sql`, `.toml`, `.ts`, `.yaml` and the other suffixes it colours, its own rules are used)
234
301
  - **UI translations** — new interface languages
235
302
  - **Run configurations** — "Run with…" for interpreted (`go run main.go`) and compiled (`gcc main.c -o main` then run) languages, executed through PyBreeze's `FileRunnerProcess` with the compiled artifact cleaned up afterwards
236
- - **Plugin Browser** — browse and install plugins from remote repositories inside the IDE
303
+ - **Plugin Browser** — browse and install plugins from remote repositories inside the IDE, from **Plugins → Plugin Browser**, which is there before any plugin is installed; an installed plugin loads at the next start
237
304
 
238
305
  Loaded plugins appear under their own **Plugins** menu with an About entry and one run action, labelled with the suffixes it runs. [PLUGIN_GUIDE.md](PLUGIN_GUIDE.md) covers what PyBreeze adds and links JEditor's guide, which has the full API and worked examples (C, C++, Go, Java, Rust, and a French translation).
239
306
 
@@ -244,7 +311,7 @@ Loaded plugins appear under their own **Plugins** menu with an About entry and o
244
311
  - **English** (default)
245
312
  - **Traditional Chinese** (繁體中文)
246
313
 
247
- Both dictionaries carry the same 708 keys, and a test enforces that parity so a new string can never land in one language only. Further languages can be added via translation plugins.
314
+ Menus, dialogs, the reasons a tool refuses its input and the run window's own notices (`[Error] …`, `[Run] …`) all follow the chosen language. Both dictionaries carry the same 995 keys, and a test enforces that parity so a new string can never land in one language only. English and Traditional Chinese are the languages PyBreeze maintains. The Language menu also lists JEditor's Japanese (日本語) and Simplified Chinese (简体中文), which PyBreeze passes on without translating: picked, JEditor's own menus change and PyBreeze's strings stay in English. Further languages can be added via translation plugins.
248
315
 
249
316
  ---
250
317
 
@@ -328,6 +395,13 @@ For a module-by-module walkthrough of the codebase, see [architecture_explore.md
328
395
  pip install pybreeze
329
396
  ```
330
397
 
398
+ The development channel follows the `dev` branch. CI publishes a new `pybreeze_dev` each time a push to
399
+ `dev` passes the tests and changes what the package ships:
400
+
401
+ ```bash
402
+ pip install pybreeze_dev
403
+ ```
404
+
331
405
  ### From source
332
406
 
333
407
  ```bash
@@ -354,18 +428,29 @@ python exe/start_pybreeze.py # from the exe directory
354
428
  ```python
355
429
  from pybreeze import start_editor
356
430
 
357
- start_editor() # default dark_amber theme
358
- start_editor(theme="dark_teal.xml") # any qt_material theme
431
+ start_editor() # the theme picked from UI Style (dark_amber until one is)
432
+ start_editor(theme="dark_teal.xml") # any qt_material theme; it becomes the picked one
359
433
  ```
360
434
 
361
435
  Once launched:
362
436
 
363
- 1. **Write** an automation script in the editor — automation keywords highlight as you type
437
+ 1. **Write** an automation script in the editor
364
438
  2. **Run** it from the `Automation` menu, picking the target module
365
439
  3. **Watch** the output stream into the run window
366
440
  4. **Generate** an HTML / JSON / XML report
367
441
  5. **Send** it by email through the MailThunder integration
368
442
 
443
+ New here? The [tutorials](https://pybreeze.readthedocs.io/en/latest/Eng/tutorials/index.html) are thirteen short pages, each with an example that runs and what to expect from it: the first launch, a first API, browser, desktop and load run, tests from cURL and HAR, header findings as SARIF in CI, the JSON editor, keywords for action scripts, the MCP client, reports in CI, plugins, and troubleshooting. They test a small site on your own machine, so none of them needs an account.
444
+
445
+ ### Log file
446
+
447
+ PyBreeze writes its log to `~/.pybreeze/logs/PyBreeze.log`: UTF-8, appended to by every run, each line carrying the process ID. Only warnings and errors also appear in the editor's Code Result panel. Two environment variables change this:
448
+
449
+ | Variable | Effect |
450
+ |---|---|
451
+ | `PYBREEZE_LOG_FILE` | The log file to write instead |
452
+ | `PYBREEZE_LOG_MAX_BYTES` | When a PyBreeze process first writes to the log and the file is larger than this many bytes, the file is first renamed with `.1` appended, replacing the previous one (default 104857600, 100 MB; `0` never renames it) |
453
+
369
454
  ---
370
455
 
371
456
  ## Integrated Automation Modules
@@ -377,7 +462,7 @@ Once launched:
377
462
  | **WebRunner** | Browser driver integration, element location and interaction, web test scripting, reports |
378
463
  | **LoadDensity** | Concurrent request simulation, performance metrics, stress scenario management, reports |
379
464
  | **MailThunder** | SMTP sending, HTML report delivery, attachments, environment-variable configuration |
380
- | **TestPioneer** | YAML test definitions, template generation, structured execution |
465
+ | **TestPioneer** | YAML test definitions, template generation, structured execution; `Install ▸ Automation ▸ Install TestPioneer` installs or upgrades it (0.1.34 and later read a YAML file as UTF-8 whatever the system locale) |
381
466
  | **File Automation** | Automated file and directory operations, batch processing |
382
467
  | **prthinker** | Chain-of-thought code review of a file or a Pull Request; settings in `~/.pybreeze/prthinker_setting.json`; installed from its own source folder via `Install ▸ Automation ▸ Install prthinker` (needs Python 3.12+) |
383
468
 
@@ -396,8 +481,6 @@ PyBreeze/
396
481
  │ │ │ ├── process_executor_utils.py # build_process / start_process
397
482
  │ │ │ ├── file_runner_process.py # Plugin run configs (any language)
398
483
  │ │ │ ├── queue_pump.py # Shared pipe reader + QTimer drain
399
- │ │ │ ├── api_testka/ auto_control/ web_runner/
400
- │ │ │ ├── load_density/ file_automation/ mail_thunder/
401
484
  │ │ │ ├── test_pioneer/ prthinker/
402
485
  │ │ ├── mail_thunder_extend/ # Post-test email report hook
403
486
  │ │ └── prthinker_extend/ # prthinker settings & argument assembly
@@ -416,10 +499,13 @@ PyBreeze/
416
499
  │ └── utils/ # curl/HAR parsing, headers, JWT, hashing,
417
500
  │ # URL validation, logging, exceptions, …
418
501
  ├── exe/ # Standalone launcher & build configs
419
- ├── docs/ # Sphinx documentation source
502
+ ├── docs/ # Sphinx documentation source; updates/ is the change log
420
503
  ├── test/ # Unit tests (test_utils) + startup tests
504
+ ├── scripts/ # Release helper for the dev channel (dev_release.py)
421
505
  ├── images/ # Screenshots
506
+ ├── architecture.md # Architecture overview: layers, flows, cross-project contracts
422
507
  ├── architecture_explore.md # Module-by-module architecture notes
508
+ ├── progress.md # Work still to do
423
509
  ├── PLUGIN_GUIDE.md # Plugin development documentation
424
510
  ├── pyproject.toml # Package configuration (stable)
425
511
  ├── dev.toml # Package configuration (dev channel)
@@ -459,9 +545,9 @@ python -m pip install -r dev_requirements.txt
459
545
  python -m pytest test/test_utils/ -v --tb=short
460
546
  ```
461
547
 
462
- - **Unit tests** — `test/test_utils/`, covering the pure-logic layer (curl and HAR parsing, header analysis, SSRF validation, JWT, hashing, timestamps, diffing) plus headless Qt widget tests via `QT_QPA_PLATFORM=offscreen`, with Hypothesis property tests over the parsers
548
+ - **Unit tests** — `test/test_utils/`, covering the pure-logic layer (curl and HAR parsing, header analysis, SSRF validation, JWT, hashing, timestamps, diffing) plus headless Qt widget tests via `QT_QPA_PLATFORM=offscreen`, with Hypothesis property tests over the parsers. The SSH terminal and the SFTP file tree also log in to an SSH server the tests start on the loopback address, which serves a temporary folder over SFTP
463
549
  - **Startup tests** — `test/unit_test/start_automation/` launches the IDE in debug mode and verifies it comes up and exits cleanly
464
- - **CI** — GitHub Actions on Windows across Python 3.10 – 3.14, on every push and PR plus a nightly run
550
+ - **CI** — GitHub Actions: the whole suite on Windows across Python 3.10 – 3.14, and a short set of platform smoke tests on Linux and macOS, on every push and PR plus a nightly run; a push to `dev` that passes the suite also publishes `pybreeze_dev` when the package changed
465
551
  - **Static analysis** — SonarCloud, Codacy and Bandit
466
552
 
467
553
  ---