comate-cli 0.12.4b9__tar.gz → 0.12.4b11__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.
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/CONTEXT.md +72 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/PKG-INFO +2 -2
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/animations.py +47 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/app.py +4 -0
- comate_cli-0.12.4b11/comate_cli/terminal_agent/config/edit_session.py +172 -0
- comate_cli-0.12.4b11/comate_cli/terminal_agent/config/picker.py +275 -0
- comate_cli-0.12.4b11/comate_cli/terminal_agent/config/picker_state.py +102 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config/store.py +118 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/event_renderer.py +85 -8
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/__init__.py +3 -3
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/_en.py +60 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/_ja.py +59 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/_zh.py +50 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/message.py +43 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/locale.py +4 -0
- comate_cli-0.12.4b11/comate_cli/terminal_agent/menu_panel.py +210 -0
- comate_cli-0.12.4b11/comate_cli/terminal_agent/plugins/marketplace_install_view.py +407 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/plugin_picker.py +110 -71
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/installed_tab.py +94 -4
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/marketplaces_tab.py +103 -78
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/recap/controller.py +10 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/selection_menu.py +105 -83
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/skill_slash_input.py +30 -3
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/model.py +1 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/suggestion/controller.py +11 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/theme.py +4 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_fold.py +1 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_formatters.py +132 -15
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/transcript_viewer.py +252 -77
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui.py +59 -8
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/btw_view.py +4 -47
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/commands.py +199 -67
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/input_behavior.py +23 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/key_bindings.py +85 -13
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/mcp_connecting_view.py +25 -58
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/pyproject.toml +7 -2
- comate_cli-0.12.4b11/tests/config/test_config_exit.py +131 -0
- comate_cli-0.12.4b11/tests/config/test_edit_session.py +260 -0
- comate_cli-0.12.4b11/tests/config/test_picker_state.py +65 -0
- comate_cli-0.12.4b11/tests/config/test_picker_ui.py +93 -0
- comate_cli-0.12.4b11/tests/config/test_runtime_settings.py +105 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/conftest.py +17 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/test_model.py +3 -3
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/test_picker_state.py +1 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/test_store.py +2 -2
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_next_step_suggestion_render.py +25 -2
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_tab_accepts_next_step_suggestion.py +22 -4
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_ctrl_b.py +3 -0
- comate_cli-0.12.4b11/tests/test_event_renderer_budget_floor.py +189 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_installed_tab.py +323 -2
- comate_cli-0.12.4b11/tests/test_loading_line_fragments.py +116 -0
- comate_cli-0.12.4b11/tests/test_marketplace_add_commands.py +149 -0
- comate_cli-0.12.4b11/tests/test_marketplace_install_view.py +258 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_marketplaces_tab.py +257 -100
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_slash_command.py +20 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_menu_cursor_unification.py +9 -7
- comate_cli-0.12.4b11/tests/test_menu_panel.py +229 -0
- comate_cli-0.12.4b11/tests/test_menu_panel_pty.py +119 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_tui_components.py +80 -71
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_v4_stdio_smoke.py +1 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_shell_mode.py +3 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_skill_slash_input.py +177 -22
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar.py +12 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_theme.py +3 -2
- comate_cli-0.12.4b11/tests/test_tool_call_protection.py +99 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_fold_panel.py +30 -25
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_formatters.py +18 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_state.py +1 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_view.py +4 -2
- comate_cli-0.12.4b11/tests/test_transcript_viewer.py +606 -0
- comate_cli-0.12.4b11/tests/test_transcript_viewer_record_matching.py +130 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_transcript_viewer_tool_fold.py +35 -4
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_queue_sdk_source.py +61 -1
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_surrogate_repair.py +1 -0
- comate_cli-0.12.4b11/tools/transcript_viewer_bench.py +250 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/uv.lock +27 -2
- comate_cli-0.12.4b9/comate_cli/terminal_agent/config/picker.py +0 -252
- comate_cli-0.12.4b9/comate_cli/terminal_agent/config/picker_state.py +0 -245
- comate_cli-0.12.4b9/comate_cli/terminal_agent/plugins/marketplace_install_view.py +0 -285
- comate_cli-0.12.4b9/tests/config/test_picker_state.py +0 -300
- comate_cli-0.12.4b9/tests/config/test_picker_ui.py +0 -147
- comate_cli-0.12.4b9/tests/test_transcript_viewer.py +0 -249
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/bash/3b0c312b1a234220818cb8cc15a12ea1565c69dc5f828351a492dab1add0cf84.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/bash/b0696d5d44fdde7597b8e9bd706d61237290ebca0c1c99273799393a7af99316.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/bash/e1164ab5f5f1e125db38bb44420532265c958f19533fbda8700db5a8aa4c3d68.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/00f8013ce28fed8e3076db6490d6a3de8dbc1f57f5248a1f5e2710f11ab6849c.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/0a5f3319bc1813a523b8d041831399f3ea694fcdb96f4b1df740300d08c60521.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/17dc19a9b5faddcd056013e7783c8d23525d060b7b20a73ee241c569bedea6d8.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/2b488f719c3431607773d9cebef4924ebfa33745adc68d8ee0f89596c608a218.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/32ce175150a77180dda04a76ea66b9ee5b0c46ea0fd0842172bacece964d57a4.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/43166c9eb998d1a426ce0c014348e39adc8c8e1d3d7a94ced4cc33ab268ecdeb.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/4afc47414280761b7c94ff91f7477c4eb5602396da89303b403c6f3ef9535fd0.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/56fca6c3112743a94cd0df58e04ee6dda31546ed53d50f8bf907dccb6f5329d3.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/605fcb1ca26d1cb632e364dd044d280a12ad4f188db698d5bad57fe1ff556ce3.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/6763a04477b314da76472e76696c8b03ee89fffc23ce74a22c634ea373840acd.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/6d1856ff719ee695ed9205cf68723a263f8c70fe090295037c1c9a837f8eac13.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/6e08c59431a214d8c3650a701cbaaf9125503d59d28476642f8b5a0ad6c8ed93.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/746f6a3b34e30583972816a0052d99e8297096ba522d66027b085e3a0069b7db.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/7c8fa2270ca7721e8619ba7eaec744100877330317dd5e8a1e42494a09579317.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/7cc3e32a61277dc3e35039fdc1cac3691e147cd50d8d16fa75447de7d11abb77.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/8203d4eaf35b0bb224cb12067e638b7f873ae0af05a590adedc02ae159a08099.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/82a7ce335091c00f8aee0ff54b6a75ed25fb6f7a2f4bf8d29921c3f2704ada81.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/82e9a29128ad224555ae0e85dddcc118d92a8f4faf4c8a3c3702c6b43dc71511.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/83be41699a979e16de16f3095981346f337fda56a3c254420df953e2de87d982.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/84074b6fda0e110d23094926c0d1846130be2b3870b1bcd5516243bae808b209.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/a92368734a2d79c15eaba1c7d282bab2d4150ccde0e41e30628cfb6b7be6a678.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/b02349374e026c124a60335b4b0e77698e4b7f8391f2466c827f6f80a8d596b2.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/b41279d93d2b1f03e99bf2fdcd4477781edf3546256489e2d37f082fa414ef94.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/bde0cfc02d38109cc02a28dd07611e464db9b47fef8b16fc25591866e5003316.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/c0e234da2bfe338ffbce547372af90d36ce7580361b69664823d12fac048a86e.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/c979b9589e166ae451c819fc8fc1efdf9eb042ce7af99e420a5b540f0d041a7a.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/dd39676b55965a3e04c1b28c82cd9c15e335776f39f325f61854d3e48aa87859.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/dec1ee9f38d117f649d0ba2cfb54b50d9ccd841833170c49614fa181a358013e.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/eac0d88d65c24b10af556c030b795f3312cc70fc80f8f64575205ea1a6476264.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/ef063804b585209aafbded7c27ad8d5eacbad17b3bb967022290a9efd01f6d13.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/f75a98ad1ac3c085060f90492292060b3720dfa98c776e61a643b9824d1dc237.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/faffcd8b4abd87e4abff3b72dcde673e844a4d7e230fbcc5c116ddd11815c37b.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/fb29e07995891317ca0daa3257e541238908889bc7a68efeba695c8ac3a2db86.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/feed470ec463825f43ae4e1b92a5996b1dbad91605fe491f39c9ee60879b7155.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/index.json +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/ls/5a0a29a96857998fdfe5696c09b9c60027a6529e21108e22a20f5227afeddb59.json +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/1f093e98c0f4026921bb2df0c7c04d6b55b51ec40c9fbf38ba57bd387399127d.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/57c31009cc3665a6a672811ecf048cfb75ff7bae92598df943f492c53d39ca8e.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/916a2e47f13fd22d3a73a4896c7a5edb3381b8a2c8322ce3ab8a4bf9da94c4a0.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/91f5872f5b4b1b43f16589f7dd25e47236a805e848b37307cef464e881307fe1.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/9871dc91ff9afef1303c74cf669996828a7db3dbff6c4c41fbac0a53fd7d195b.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/af594562a5579ffc9bef105dc77ed26408b2408447005046c9c6505541e2776a.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/c52ec3da48b3a731ed42cc357258a4627d2d11fab5ef14d3050fd50e748151d4.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/f8c08a56feb0812b35a8e4b29a721d38c0aacd83ce3620c432d8b52114c14816.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/fa30187a59d255f168806ee0de7a0a32b00535e53e7c5420aad1bac44b54a667.txt +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/scheduled_prompts.json +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.gitignore +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/CHANGELOG.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/README.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/__main__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/device_identity.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/distribution.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/main.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/mcp_cli.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/approval_bridge.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/approval_content_preview.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/assistant_render.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/announcements.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/client.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/feedback.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/provider_snapshot.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/rating.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/runtime.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/session_report.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/session_title.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/tasks.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/bash_command_display.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/.keep +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/commit.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/implement-plan.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/learn.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/open-pr.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/clipboard_image.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/codenames.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config/model.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config_check.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/console_profile.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/context_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/custom_slash_commands.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/effort_menu.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/effort_ruler.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/effort_style.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/env_utils.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/error_display.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/exit_confirm_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/exit_watchdog.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/figures.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/file_ref_hint.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/fragment_utils.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/goal_edit_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/goal_resume_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/history_printer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/image_chips.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/input_geometry.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/jobs_picker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/jobs_state.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/layout_coordinator.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/logging_adapter.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/logging_file_handler.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/logo.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/markdown_render.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/mcp_serve.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/mention_completer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/message_style.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/model_tier_style.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/models.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/output_style_menu.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/auto_update_runner.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/auto_update_store.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/detail_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/plugin_list.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/search_box.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/tab_bar.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/operation_state.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/discover_tab.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/errors_tab.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/preflight.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/preflight_wizard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/preflight_wizard_ui.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/print_mode.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/question_broker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/question_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/recap/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/resume_picker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/resume_preview.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/resume_selector.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_commands.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_relay.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_stdio.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_ws.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/scm_request_status.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/side_install.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/sigint_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/skills_menu.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/slash_commands.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/startup.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/startup_profile.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/status_bar.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/picker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/picker_state.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/store.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/stream_pacer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/suggestion/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/synchronized_output.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/text_effects.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tips.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_approval_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_fold_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_state.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_store.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_viewer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/approval_queue.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/history_sync.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/render_panels.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/resize_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/run_clock.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/shell_mode.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/slash_command_registry.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/ui_mode.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/ultracode_keyword.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/update_check.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/update_messages.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/workflows_panel.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/workflows_panel_model.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_title.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/update_cli.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/cli-rpc-stdio-guide.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/release-notes/0.12.3.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/startup-performance.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/superpowers/plans/2026-07-07-tui-first-repaint-before-sdk-submit.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/superpowers/plans/2026-07-07-windows-update-manual-rollback.md +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/_fake_anthropic_server.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/_rpc_ws_client.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_model.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_roundtrip.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_skills_denylist_migration.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_store_load.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_store_save.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/fixtures/exit_watchdog_child.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/fixtures/fake_mcp_misbehaving_stdout.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/recap/test_idle_recap_controller.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/recap/test_recap_history_rendering.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/recap/test_tui_idle_recap_integration.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/__init__.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_next_step_suggestion_controller.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_tui_next_step_suggestion_integration.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_animations_styles.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_animator_shuffle.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_config_check_gate.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_exit_lifecycle.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_mcp_preload.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_mcp_preload_kick.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_preflight_gate.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_print_mode.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_profile_threading.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_ctrl_c_exit.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_shell_mode.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_smoke.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_shutdown.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_startup_latency.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_startup_order.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_token_cost_config.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_usage_line.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_approval_bridge.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_approval_content_preview.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_announcements.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_client.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_feedback.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_provider_snapshot.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_rating.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_session_report.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_tasks.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_btw_slash_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_busy_slash_gating.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_cli_project_root.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_clipboard_image_reader.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_commands_system_messages.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_compact_command_semantics.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_completion_context_activation.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_completion_status_panel.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_config_check.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_console_profile.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_context_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_context_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ctrl_b_background.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ctrl_c_clear_input.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_custom_slash_commands.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_device_identity.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_discover_tab.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_distribution_contract.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_drain_frame_atomicity.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_menu.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_menu_frame_rate.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_ruler.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_slash_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_style.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_errors_tab.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_approval_wait.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_boundary.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_e2e.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_fixed_overhead.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_idle_prune.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_jobs.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_log_boundary.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_log_queue.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_provider_overflow.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_shell.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_stream_pacing.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_stream_staging.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_streaming.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_tool_args_progress.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_tool_fold.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_confirm_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_watchdog.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_watchdog_subprocess.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_file_ref_hint.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_format_error.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_edit_handlers.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_edit_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_paused_hint.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_resume_tui.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_resume_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_slash_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_handle_error.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_drain_throttle.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_log.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_styles.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_subtitle_position.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_tool_fold.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_sync.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_sync_tool_fold.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_i18n.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_image_chips.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_image_preprocess_offload_lag.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_import_weight.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_input_behavior.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_input_history.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_input_separator_counter.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_interrupt_exit_semantics.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_jobs_panel.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_jobs_picker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_key_bindings_system_messages.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_layout_coordinator.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_loading_modal_suppression.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_loading_tip_picker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_logging_adapter.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_logging_file_handler.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_logo.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_main_args.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_main_args_yolo.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_main_profile_entry.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_markdown_render.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_cli.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_cli_scope_defaults.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_serve.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mention_completer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_message_style.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_modal_freeze_timing.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_modal_panel_visibility.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_model_switch_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_model_tier_style.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_no_raw_colors.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_output_style_slash_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_permission_mode_cycle.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_auto_update_runner.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_auto_update_store.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_auto_update_tui.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_operation_state.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_slash_commands.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_preflight.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_preflight_copilot.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_preflight_wizard_ui.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_pty_output_integrity.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_question_broker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_question_key_bindings.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_question_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resize_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_picker.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_picker_exit_safety.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_preview.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_selector.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rewind_command_semantics.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_mode_logging.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_relay_dial_out.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_relay_e2e_smoke.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_relay_process_smoke.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_v4_ws_smoke.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_ws_bind_failure.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_run_clock.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_running_tool_status_line.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_scm_request_status.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_scrollback_write_encoding.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_selection_menu.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_session_auto_title.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_session_query_token_summary.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_settings_write_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_shutdown_noise_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_shutdown_noise_integration.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_side_install.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_sigint_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_sigint_key_binding.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_skills_slash_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_add_dir.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_argument_hint.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_clear.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_completer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_registry.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_startup_import_budget.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_startup_profile.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar_mid_turn_refresh.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar_request_status.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar_transient.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_stream_pacer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_stream_pacing_tick.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_stream_staging_panel.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_style_class_coverage.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_synchronized_output.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tab_title.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_panel_format.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_panel_key_bindings.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_panel_rendering.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_poll.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_terminal_title.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tips.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_todo_panel_busy_gating.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_key_bindings.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_tui.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_view_workflow.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_fold.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_fold_view.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_store.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_viewer.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_viewer_key_bindings.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_view_styles.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_builtin_slash_chain.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_deferred_prewarm.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_elapsed_status.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_esc_queue.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_exit_idempotence.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_exit_paced_tail.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_exit_pending_logs.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_hot_reload.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_chip_seed.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_paste.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_path_upgrade.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_restore.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_submit.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_interrupt_queue_recall.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_llm_retry_panel.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_loading_tip_rotation.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_local_interactive_barrier.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_mcp_init_gate.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_paste_history_persistence.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_paste_newline_guard.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_paste_placeholder.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_plugin_load.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_provider_error_shield.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_queue_pop_images.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_queue_preview.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_replace_session_resume_hint.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_scheduled_fire_log.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_scratchpad_fold_wiring.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_send_undo_window.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_session_observers.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_shutdown_cancel_propagation.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_split_invariance.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_startup_latency.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_thinking_display.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_tool_result_registry_lifecycle.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_window_too_small_fallback.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ui_mode_derivation.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ui_tick_exception_isolation.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_keyword.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_keyword_frame_rate.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_keyword_submit.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_shimmer_render.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_update_check.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_update_cli.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_upstream_surrogate_merge_characterization.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_usage_command.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_wellformed_terminal_input.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_whitelabel_clear_logo.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_windows_sigint_console.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_workflows_panel.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_workflows_panel_model.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_wrap_user_text.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_zipapp_launcher_path.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/diagnose_windows_shim_rename.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/logo_lab.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/nico_preview.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/probe_conhost_char_width.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/probe_conhost_render_replay.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/startup_bench.py +0 -0
- {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/verify_windows_self_update_semantics.py +0 -0
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Comate CLI Domain Model
|
|
2
2
|
|
|
3
|
-
Canonical language for Comate CLI command discovery, transient terminal display, session reporting boundaries, and plugin auto update.
|
|
3
|
+
Canonical language for Comate CLI command discovery, slash input completion, menu panels, transient terminal display, session reporting boundaries, and plugin auto update.
|
|
4
|
+
|
|
5
|
+
## Menu Panel Language
|
|
6
|
+
|
|
7
|
+
**Menu Panel(菜单面板)**:
|
|
8
|
+
由 slash 命令打开的暂态操作界面。多个菜单使用一致的视觉与导航规则,关闭后返回对话输入。
|
|
9
|
+
_Avoid_: menu output(菜单输出), history block(历史块)
|
|
10
|
+
|
|
11
|
+
**Settings Edit Session(设置编辑会话)**:
|
|
12
|
+
从打开设置面板到保留或取消更改的一次编辑过程。更改即时保存;保留操作接受这些更改,取消操作撤销本次仍未被外部再次修改的更改。
|
|
13
|
+
_Avoid_: settings draft(设置草稿), save-on-close(关闭时才保存)
|
|
4
14
|
|
|
5
15
|
## Slash Command Language
|
|
6
16
|
|
|
@@ -19,6 +29,30 @@ Describes how a registered command is dispatched. Values: `"builtin"` (hardcoded
|
|
|
19
29
|
The slash entry of a runtime skill that is enabled and user-invocable. Its name is the skill's call name; plugin skills carry a `namespace:` prefix and so never collide with plain names. A skill that is disabled or declares `user-invocable: false` has no slash entry and claims no name. When its name is shadowed by a higher-priority command, the skill stays callable by the model through the Skill tool; only the slash entry is lost, and the user is told once per name per process.
|
|
20
30
|
_Avoid_: skill command (ambiguous with custom command)
|
|
21
31
|
|
|
32
|
+
**Skill Slash Mention**:
|
|
33
|
+
A complete call name of a model-visible skill appearing in prose with a valid whitespace/punctuation boundary before and after. A mention is the authorization fact that drives the model-visible reminder injection and, together with Inline Skill Invocation, the in-prose highlight; a typing-in-progress prefix is never a mention.
|
|
34
|
+
_Avoid_: slash reference, skill authorization (names the effect), partial mention
|
|
35
|
+
|
|
36
|
+
**Inline Skill Invocation**:
|
|
37
|
+
A complete call name of a user-only skill (user-invocable, `disable-model-invocation: true`) appearing in prose with the same boundaries as a Skill Slash Mention. The system loads that skill's prompt into the user's turn right after the user's text, the way a Head Slash call does; it never authorizes the model.
|
|
38
|
+
_Avoid_: inline slash command, middle slash invocation, mention (names the authorization path)
|
|
39
|
+
|
|
40
|
+
**Skill Slash Token**:
|
|
41
|
+
The incomplete slash-prefixed fragment at the cursor while typing: the slash plus the name characters typed so far, whitespace-free. The raw material of middle skill completion. It becomes a Skill Slash Mention only when the typed characters are the complete call name.
|
|
42
|
+
_Avoid_: partial mention, prefix mention
|
|
43
|
+
|
|
44
|
+
**Head Slash / Middle Slash**:
|
|
45
|
+
The two position classes of a Skill Slash Token in the input box. Head Slash: the whole buffer is one token — the head command menu's territory, matched by subsequence fuzzy completion. Middle Slash: a token after a whitespace boundary inside the buffer — the middle skill completion's territory, matched by Trailing Segment Match. A slash at the start of a later line is a Middle Slash; only buffer position zero is Head.
|
|
46
|
+
_Avoid_: 行首/中段 as canonical terms, line-initial slash (wrong for later lines), in-prose slash
|
|
47
|
+
|
|
48
|
+
**Trailing Segment Match**:
|
|
49
|
+
The matching semantics of middle skill completion: a Skill Slash Command matches when its full name, or the segment after its last namespace colon, starts with the typed name characters case-insensitively. `/grill` matches `mattpocock-skills:grilling` via its trailing segment. Mention judgment never follows this relaxation.
|
|
50
|
+
_Avoid_: substring match, fuzzy match (the head menu's semantics)
|
|
51
|
+
|
|
52
|
+
**Middle Slash Preview**:
|
|
53
|
+
The gray text after a Middle Slash token at the end of the input: the remaining characters of the chosen Skill Slash Command's name, or of its trailing segment when it matches through that segment alone. It is display-only; only Tab acts on it, and Tab always writes the full slash name.
|
|
54
|
+
_Avoid_: ghost text, inline suggestion, 灰字建议
|
|
55
|
+
|
|
22
56
|
**Source Axis** (`CustomSlashCommand.source_scope`):
|
|
23
57
|
Describes where a markdown-template command's definition lives. Values: `"project"`, `"user"`, `"plugin"`, `"default"`. Determines override priority only.
|
|
24
58
|
|
|
@@ -46,6 +80,14 @@ _Avoid_: typewriter effect (that is character-level), throttling (that is the sc
|
|
|
46
80
|
The short English phrase in the breathing-yellow part of the loading line's status suffix, shown only while the model thinks and thinking display is off. It names the thinking effort that the in-flight request actually uses (the applied level, or ultracode when that switch is on). It is chosen when a request starts to think and does not change until that request ends. When no applied level is known, it shows the neutral word `thinking`. It is a word, not a color: it never takes the effort level colors.
|
|
47
81
|
_Avoid_: effort badge, hidden thinking label, random thinking word
|
|
48
82
|
|
|
83
|
+
**Tool Args Progress**:
|
|
84
|
+
The `↓ N tokens` part of the loading line's status suffix: an estimate of how large the arguments of the tool call the model is still generating have grown so far. It appears only after the arguments pass a visibility threshold, and it can only move when the provider delivers the arguments incrementally; a provider that delivers them in one piece at the end leaves nothing to show. It concerns the main agent's in-flight request only.
|
|
85
|
+
_Avoid_: token 下行状态 (reads as network bytes), download progress, output token counter
|
|
86
|
+
|
|
87
|
+
**Buffered Tool Args**:
|
|
88
|
+
A provider behavior in which a streaming response holds back a tool call's name and arguments and delivers them in one piece at the end, instead of incrementally as they are generated. While it lasts, nothing tells the CLI that a tool call has begun, so Tool Args Progress cannot appear. Some endpoints buffer by default and stream incrementally only when the request opts in.
|
|
89
|
+
_Avoid_: 攒包, non-streaming tool call (the response is still a stream)
|
|
90
|
+
|
|
49
91
|
**Immutable Scrollback Commit**:
|
|
50
92
|
The point at which staged terminal output is appended to terminal scrollback and can no longer be replaced. An open Streaming Markdown Container remains transient until its closing boundary or a normal turn boundary makes it complete.
|
|
51
93
|
_Avoid_: history render, live Markdown rerender
|
|
@@ -114,6 +156,16 @@ _Avoid_: auto update enablement (inverted semantics), plugin pin (no version pin
|
|
|
114
156
|
The invariant that an update changes only on-disk plugin state. The running session keeps its already-loaded resources until the next startup or an explicit user reload. A background update therefore never shifts agent behavior mid-session.
|
|
115
157
|
_Avoid_: hot reload, live update
|
|
116
158
|
|
|
159
|
+
## Plugin Marketplace Language
|
|
160
|
+
|
|
161
|
+
**Marketplace Source**:
|
|
162
|
+
The coordinate a user types to reach a marketplace: a GitHub `owner/repo` shorthand, a git URL (https or ssh), or a direct `marketplace.json` URL. It is only an address; it carries no name.
|
|
163
|
+
_Avoid_: marketplace url (too narrow), repo (only one of the forms)
|
|
164
|
+
|
|
165
|
+
**Marketplace**:
|
|
166
|
+
A registered plugin source, named by its own manifest rather than by whatever the user typed. One Marketplace Source resolves to at most one Marketplace, however it is spelled.
|
|
167
|
+
_Avoid_: plugin store, registry (the registry is the collection of Marketplaces)
|
|
168
|
+
|
|
117
169
|
## CLI Self-Update Language
|
|
118
170
|
|
|
119
171
|
**Self-Update**:
|
|
@@ -220,6 +272,16 @@ _Avoid_: todo panel, tasklist (spoken shorthand only)
|
|
|
220
272
|
A state in which the run is alive but does not advance any task: context compaction in progress, or an LLM retry backoff countdown. Only the countdown counts as Stall Status; the retried request itself does not.
|
|
221
273
|
_Avoid_: blocking status ("blocking" in this repo means blocking the event loop), waiting state
|
|
222
274
|
|
|
275
|
+
## Event Loop Health Language
|
|
276
|
+
|
|
277
|
+
**Event Loop Lag**:
|
|
278
|
+
The measured gap between two consecutive UI ticks that exceeds the lag threshold. It tells how long the loop did not run, not where it was stuck. A lag that occurs while the TUI is idle is still an Event Loop Lag; whether it is recorded is a detector choice, not part of the term.
|
|
279
|
+
_Avoid_: slow turn (an awaited operation that is slow does not stop the loop), UI stutter
|
|
280
|
+
|
|
281
|
+
**Loop Freeze Snapshot**:
|
|
282
|
+
The main-thread stack captured from outside the loop while an Event Loop Lag is still in progress, together with the most recent first-turn phase name. It is the attribution evidence for a lag; the lag log alone is not.
|
|
283
|
+
_Avoid_: lag log, profiler output (the profiler records phase durations, not a stuck stack)
|
|
284
|
+
|
|
223
285
|
## Relationships
|
|
224
286
|
|
|
225
287
|
- A **Core Slash Command** is always registered with `source="builtin"` on the Execution Axis. Its name belongs to the **Reserved Name Set** and cannot be overridden by any markdown-template command.
|
|
@@ -229,6 +291,12 @@ _Avoid_: blocking status ("blocking" in this repo means blocking the event loop)
|
|
|
229
291
|
- **Default Custom Commands** are loaded from package resources via `importlib.resources`, parsed by the same frontmatter pipeline as project/user commands, and subject to the **Override Priority Chain** at registration time.
|
|
230
292
|
- A **Default Custom Command** parse failure is a developer-visible error (raised at discovery), not a user-visible warning, because package resources are trusted input maintained by the comate_cli maintainers.
|
|
231
293
|
- The **Reserved Name Set** gates discovery only; it prevents user-authored markdown commands from shadowing **Core Slash Commands**, and only Core Slash Commands.
|
|
294
|
+
- Only a **Middle Slash** token enters middle skill completion; a **Head Slash** token belongs to the head command menu.
|
|
295
|
+
- **Trailing Segment Match** never turns a **Skill Slash Token** into a **Skill Slash Mention**: a mention still requires the complete call name with valid boundaries.
|
|
296
|
+
- Under **Trailing Segment Match**, a full-name prefix match always outranks a match through the trailing segment alone; trailing segments only fill in when no full-name prefix matches.
|
|
297
|
+
- In middle skill completion, model-visible candidates outrank user-only candidates; user-only skills only fill in when no model-visible skill matches.
|
|
298
|
+
- Only a user-only skill forms an **Inline Skill Invocation**; a model-visible skill named in prose is always a **Skill Slash Mention**. An Inline Skill Invocation loads the skill and never authorizes the model; a mention authorizes the model and never loads the skill.
|
|
299
|
+
- A **Middle Slash Preview** and Tab always pick the same Skill Slash Command; Tab writes its full slash name even when the preview only completed the trailing segment.
|
|
232
300
|
- **Fence Boundary Recognition** belongs to the streaming lifecycle: `EventRenderer` preserves container atomicity, while Rich remains responsible for Markdown parsing, selecting the first info-string word as the lexer name, syntax highlighting, and plaintext fallback for unknown lexers.
|
|
233
301
|
- A fenced code opening or closing delimiter may have zero to three leading spaces. Four or more leading spaces retain Markdown's indented-code semantics and must not open or close a fenced container.
|
|
234
302
|
- A normally completed turn may add a synthetic closing delimiter before the **Immutable Scrollback Commit**. An interrupted turn discards its uncommitted container instead.
|
|
@@ -251,6 +319,9 @@ _Avoid_: blocking status ("blocking" in this repo means blocking the event loop)
|
|
|
251
319
|
- The **Update Effectiveness Boundary** holds for both Plugin Auto Update and manual plugin updates: neither may mutate the running session's loaded resources.
|
|
252
320
|
- An **Auto Update Opt-out** affects only Plugin Auto Update; it does not disable manual per-plugin updates.
|
|
253
321
|
|
|
322
|
+
- A **Marketplace** takes its name from its manifest, never from the **Marketplace Source** the user typed; duplicate detection therefore compares resolved sources, not names or spellings.
|
|
323
|
+
- Adding a **Marketplace** is never silent: the user confirms the **Marketplace Source** once before any clone or download starts, whether the source was typed into the panel or prefilled from a slash command argument.
|
|
324
|
+
|
|
254
325
|
- **Self-Update** and **Plugin Auto Update** are separate concepts with separate vocabularies: a **Version Check** orders versions, plugin **Update Detection** only compares for equality. Neither triggers the other.
|
|
255
326
|
- A **Side-Install** followed by an **Entrypoint Flip** is one Self-Update strategy; an in-process reinstall of the current installation is another. Which one applies is a property of the platform, not of the user's choice.
|
|
256
327
|
- **Restart-to-Apply** holds for every Self-Update strategy and mirrors the plugin **Update Effectiveness Boundary**: on-disk state changes, the running process does not.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: comate-cli
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.4b11
|
|
4
4
|
Summary: Comate terminal CLI built on comate-agent-sdk
|
|
5
5
|
Project-URL: Homepage, https://github.com/AndyLee1024/agent-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/AndyLee1024/agent-sdk
|
|
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Requires-Python: <3.14,>=3.11
|
|
17
17
|
Requires-Dist: charset-normalizer==3.4.7
|
|
18
|
-
Requires-Dist: comate-agent-sdk<0.13,>=0.12.
|
|
18
|
+
Requires-Dist: comate-agent-sdk<0.13,>=0.12.18
|
|
19
19
|
Requires-Dist: comate-rpc<0.2,>=0.1.4
|
|
20
20
|
Requires-Dist: concurrent-log-handler>=0.9.25
|
|
21
21
|
Requires-Dist: curl-cffi==0.13.0
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import random
|
|
5
|
+
import re
|
|
5
6
|
import time
|
|
6
7
|
from collections.abc import Sequence
|
|
7
8
|
from enum import Enum
|
|
@@ -281,6 +282,52 @@ def loading_spinner_glyph(frame: int) -> str:
|
|
|
281
282
|
return LOADING_SPINNER_FRAMES[frame % len(LOADING_SPINNER_FRAMES)]
|
|
282
283
|
|
|
283
284
|
|
|
285
|
+
_RGB_RE = re.compile(r"rgb\((\d+),\s*(\d+),\s*(\d+)\)")
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _rich_style_to_pt_style(rich_style: str) -> str:
|
|
289
|
+
"""把 rich style 字符串转为 prompt_toolkit fragment style 字符串。
|
|
290
|
+
|
|
291
|
+
``_cyan_sweep_text`` 输出形如 ``bold rgb(R,G,B)``,转为 ``#rrggbb bold``。
|
|
292
|
+
仅识别 ``bold`` 与 ``rgb(r,g,b)`` 两类标记。
|
|
293
|
+
"""
|
|
294
|
+
pieces: list[str] = []
|
|
295
|
+
match = _RGB_RE.search(rich_style)
|
|
296
|
+
if match is not None:
|
|
297
|
+
r, g, b = (max(0, min(255, int(match.group(i)))) for i in (1, 2, 3))
|
|
298
|
+
pieces.append(f"#{r:02x}{g:02x}{b:02x}")
|
|
299
|
+
if "bold" in rich_style:
|
|
300
|
+
pieces.append("bold")
|
|
301
|
+
return " ".join(pieces)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def sweep_fragments(phrase: str, frame: int) -> list[tuple[str, str]]:
|
|
305
|
+
"""``_cyan_sweep_text`` 的 prompt_toolkit fragments 版本(底部面板用)。
|
|
306
|
+
|
|
307
|
+
退化路径:如果 spans 缺失,整段返回默认样式。
|
|
308
|
+
"""
|
|
309
|
+
rich_text = _cyan_sweep_text(phrase, frame)
|
|
310
|
+
plain = rich_text.plain
|
|
311
|
+
spans = list(getattr(rich_text, "_spans", []) or [])
|
|
312
|
+
if not spans:
|
|
313
|
+
return [("", plain)]
|
|
314
|
+
return [
|
|
315
|
+
(_rich_style_to_pt_style(str(span.style)), plain[span.start : span.end])
|
|
316
|
+
for span in spans
|
|
317
|
+
]
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def loading_line_fragments(phrase: str, frame: int) -> list[tuple[str, str]]:
|
|
321
|
+
"""底部面板的加载行:与主 loading 行同款——盲文 spinner(品牌青加粗)+ 流光文字。
|
|
322
|
+
|
|
323
|
+
帧号由调用方提供(全局 ``_loading_frame`` 或组件自己的 ticker),本函数不起 task。
|
|
324
|
+
"""
|
|
325
|
+
return [
|
|
326
|
+
(f"bold fg:{theme.ACCENT}", f"{loading_spinner_glyph(frame)} "),
|
|
327
|
+
*sweep_fragments(phrase, frame),
|
|
328
|
+
]
|
|
329
|
+
|
|
330
|
+
|
|
284
331
|
def _lerp_rgb(
|
|
285
332
|
start_rgb: tuple[int, int, int],
|
|
286
333
|
end_rgb: tuple[int, int, int],
|
|
@@ -1576,6 +1576,10 @@ async def run(
|
|
|
1576
1576
|
f"MCP: {', '.join(aliases)} unavailable",
|
|
1577
1577
|
duration_s=5.0,
|
|
1578
1578
|
)
|
|
1579
|
+
# 工具说明全部到位后查一次:固定开销挤掉对话空间时,第一条消息前就警告
|
|
1580
|
+
from comate_cli.terminal_agent.event_renderer import report_conversation_budget
|
|
1581
|
+
|
|
1582
|
+
await report_conversation_budget(session, renderer)
|
|
1579
1583
|
|
|
1580
1584
|
await tui.run(mcp_init=_mcp_loader, profiler=profiler)
|
|
1581
1585
|
profiler.mark("tui.run.done")
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""设置编辑的写入与撤销生命周期;磁盘工作不占用交互事件循环。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import replace
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Any, Callable
|
|
8
|
+
|
|
9
|
+
from comate_agent_sdk.utils.daemon_thread import run_sync_in_daemon_thread
|
|
10
|
+
|
|
11
|
+
from . import store
|
|
12
|
+
from .model import ConfigSnapshot
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SettingsEditSession:
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
snapshot: ConfigSnapshot,
|
|
21
|
+
*,
|
|
22
|
+
runtime_read: Callable[[str], Any] | None = None,
|
|
23
|
+
runtime_apply: Callable[[str, Any], None] | None = None,
|
|
24
|
+
) -> None:
|
|
25
|
+
self.current = snapshot
|
|
26
|
+
self._read = runtime_read
|
|
27
|
+
self._apply = runtime_apply
|
|
28
|
+
self._runtime_origin = (
|
|
29
|
+
{
|
|
30
|
+
attr: runtime_read(attr)
|
|
31
|
+
for attr in (
|
|
32
|
+
"display_thinking",
|
|
33
|
+
"stream_pacing",
|
|
34
|
+
"display_language",
|
|
35
|
+
"recap_enabled",
|
|
36
|
+
"suggestion_enabled",
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
if runtime_read is not None
|
|
40
|
+
else {}
|
|
41
|
+
)
|
|
42
|
+
self._runtime_last: dict[str, Any] = {}
|
|
43
|
+
self._edits: dict[str, store.FieldEdit] = {}
|
|
44
|
+
self.errors: tuple[str, ...] = ()
|
|
45
|
+
self.notices: tuple[str, ...] = ()
|
|
46
|
+
self.active = True
|
|
47
|
+
|
|
48
|
+
async def _disk(self, operation: Callable, *args: Any) -> Any:
|
|
49
|
+
# 不使用默认 executor。最终退出单独限制等待预算,daemon worker 不阻塞退出。
|
|
50
|
+
return await run_sync_in_daemon_thread(
|
|
51
|
+
operation,
|
|
52
|
+
*args,
|
|
53
|
+
timeout=None,
|
|
54
|
+
thread_name="config-settings-edit",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
async def change(self, attribute: str, value: Any) -> bool:
|
|
58
|
+
self.errors = ()
|
|
59
|
+
previous = self._edits.get(attribute)
|
|
60
|
+
try:
|
|
61
|
+
runtime_before = (
|
|
62
|
+
self._read(attribute)
|
|
63
|
+
if attribute in self._runtime_origin and self._read
|
|
64
|
+
else None
|
|
65
|
+
)
|
|
66
|
+
except Exception as exc:
|
|
67
|
+
logger.exception("config runtime read failed: %s", attribute)
|
|
68
|
+
self.errors = (f"{attribute}: {exc}",)
|
|
69
|
+
return False
|
|
70
|
+
result = await self._disk(store.write_field, attribute, value, previous)
|
|
71
|
+
if not result.ok:
|
|
72
|
+
self.errors = result.error_messages
|
|
73
|
+
return False
|
|
74
|
+
assert result.edit is not None
|
|
75
|
+
self._edits[attribute] = result.edit
|
|
76
|
+
try:
|
|
77
|
+
if attribute in self._runtime_origin and self._apply is not None:
|
|
78
|
+
self._apply(attribute, value)
|
|
79
|
+
self._runtime_last[attribute] = (
|
|
80
|
+
self._read(attribute) if self._read else value
|
|
81
|
+
)
|
|
82
|
+
except Exception as exc:
|
|
83
|
+
logger.exception("config runtime apply failed: %s", attribute)
|
|
84
|
+
self.errors = (f"{attribute}: {exc}",)
|
|
85
|
+
runtime_restored = True
|
|
86
|
+
try:
|
|
87
|
+
if self._apply is not None:
|
|
88
|
+
self._apply(attribute, runtime_before)
|
|
89
|
+
except Exception as restore_exc:
|
|
90
|
+
logger.exception("config runtime compensation failed: %s", attribute)
|
|
91
|
+
self.errors += (f"Runtime compensation failed: {restore_exc}",)
|
|
92
|
+
runtime_restored = False
|
|
93
|
+
self._runtime_last[attribute] = value
|
|
94
|
+
if self._read:
|
|
95
|
+
try:
|
|
96
|
+
self._runtime_last[attribute] = self._read(attribute)
|
|
97
|
+
except Exception:
|
|
98
|
+
logger.exception(
|
|
99
|
+
"config runtime compensation read failed: %s", attribute
|
|
100
|
+
)
|
|
101
|
+
# 只撤销这一次写入;更早成功的本次编辑仍可在取消时回滚。
|
|
102
|
+
step = store.FieldEdit(
|
|
103
|
+
attribute,
|
|
104
|
+
result.step_before or result.edit.before,
|
|
105
|
+
result.edit.after,
|
|
106
|
+
)
|
|
107
|
+
compensation = await self._disk(store.rollback_field, step)
|
|
108
|
+
if compensation.ok and not compensation.conflict:
|
|
109
|
+
if not runtime_restored:
|
|
110
|
+
self._edits[attribute] = store.FieldEdit(
|
|
111
|
+
attribute,
|
|
112
|
+
result.edit.before,
|
|
113
|
+
step.before,
|
|
114
|
+
result.edit.original_value,
|
|
115
|
+
)
|
|
116
|
+
elif previous is None or step.before != previous.after:
|
|
117
|
+
self._edits.pop(attribute, None)
|
|
118
|
+
else:
|
|
119
|
+
self._edits[attribute] = previous
|
|
120
|
+
else:
|
|
121
|
+
self.errors += compensation.error_messages or (
|
|
122
|
+
"Compensation conflicted; external value retained.",
|
|
123
|
+
)
|
|
124
|
+
return False
|
|
125
|
+
self.current = replace(self.current, **{attribute: value})
|
|
126
|
+
return True
|
|
127
|
+
|
|
128
|
+
def keep(self) -> None:
|
|
129
|
+
self.active = False
|
|
130
|
+
self.errors = ()
|
|
131
|
+
self._edits.clear()
|
|
132
|
+
self._runtime_last.clear()
|
|
133
|
+
|
|
134
|
+
async def cancel(self) -> bool:
|
|
135
|
+
errors = []
|
|
136
|
+
notices = list(self.notices)
|
|
137
|
+
for attribute, edit in tuple(self._edits.items()):
|
|
138
|
+
result = await self._disk(store.rollback_field, edit)
|
|
139
|
+
if not result.ok:
|
|
140
|
+
errors.extend(
|
|
141
|
+
f"{attribute}: {error}" for error in result.error_messages
|
|
142
|
+
)
|
|
143
|
+
continue
|
|
144
|
+
if result.conflict:
|
|
145
|
+
notices.append(f"{attribute}: external change retained")
|
|
146
|
+
elif attribute in self._runtime_last and self._apply is not None:
|
|
147
|
+
try:
|
|
148
|
+
if (
|
|
149
|
+
self._read is None
|
|
150
|
+
or self._read(attribute) == self._runtime_last[attribute]
|
|
151
|
+
):
|
|
152
|
+
self._apply(attribute, self._runtime_origin[attribute])
|
|
153
|
+
else:
|
|
154
|
+
notices.append(f"{attribute}: external runtime change retained")
|
|
155
|
+
except Exception as exc:
|
|
156
|
+
logger.exception("config runtime rollback failed: %s", attribute)
|
|
157
|
+
errors.append(f"{attribute}: {exc}")
|
|
158
|
+
# 磁盘已恢复,重试时仍需重试运行时,而不能把原值误判成外部修改。
|
|
159
|
+
self._edits[attribute] = store.FieldEdit(
|
|
160
|
+
attribute, edit.before, edit.before, edit.original_value
|
|
161
|
+
)
|
|
162
|
+
continue
|
|
163
|
+
if not result.conflict:
|
|
164
|
+
self.current = replace(self.current, **{attribute: edit.original_value})
|
|
165
|
+
self._edits.pop(attribute, None)
|
|
166
|
+
self._runtime_last.pop(attribute, None)
|
|
167
|
+
self.errors = tuple(errors)
|
|
168
|
+
self.notices = tuple(notices)
|
|
169
|
+
if errors:
|
|
170
|
+
return False
|
|
171
|
+
self.active = False
|
|
172
|
+
return True
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"""采用共享内联菜单布局的 /config 编辑器。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Any, Callable
|
|
8
|
+
|
|
9
|
+
from prompt_toolkit.application.current import get_app_or_none
|
|
10
|
+
from prompt_toolkit.data_structures import Point
|
|
11
|
+
from prompt_toolkit.layout import HSplit, Window
|
|
12
|
+
from prompt_toolkit.layout.controls import FormattedTextControl
|
|
13
|
+
|
|
14
|
+
from comate_cli.terminal_agent.i18n import i18n, message
|
|
15
|
+
from comate_cli.terminal_agent.menu_panel import (
|
|
16
|
+
MenuPanel,
|
|
17
|
+
search_input,
|
|
18
|
+
setting_row,
|
|
19
|
+
terminal_size,
|
|
20
|
+
)
|
|
21
|
+
from comate_cli.terminal_agent.model_tier_style import tier_name
|
|
22
|
+
|
|
23
|
+
from .edit_session import SettingsEditSession
|
|
24
|
+
from .model import ConfigSnapshot
|
|
25
|
+
from .picker_state import (
|
|
26
|
+
ConfigField,
|
|
27
|
+
ConfigPickerState,
|
|
28
|
+
PickerExit,
|
|
29
|
+
PickerExitKind,
|
|
30
|
+
RESTART_FIELDS,
|
|
31
|
+
field_attribute,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
_FIELD_LABELS = {
|
|
37
|
+
ConfigField.DISPLAY_THINKING: "Thinking display",
|
|
38
|
+
ConfigField.STREAM_PACING: "Reply pacing",
|
|
39
|
+
ConfigField.MODEL_LEVEL: "Default model tier",
|
|
40
|
+
ConfigField.MEMORY_BACKGROUND: "Memory background",
|
|
41
|
+
ConfigField.MEMORY_DREAMING: "Memory dreaming",
|
|
42
|
+
ConfigField.TOKEN_COST: "Token cost",
|
|
43
|
+
ConfigField.RECAP: "Recap",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _field_label(field: ConfigField) -> str:
|
|
48
|
+
if field == ConfigField.LANGUAGE:
|
|
49
|
+
return i18n(message.config_language_label)
|
|
50
|
+
if field == ConfigField.SUGGESTION:
|
|
51
|
+
return i18n(message.config_suggestion_label)
|
|
52
|
+
return _FIELD_LABELS[field]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class ConfigPickerUI:
|
|
56
|
+
def __init__(self) -> None:
|
|
57
|
+
self._state: ConfigPickerState | None = None
|
|
58
|
+
self._session: SettingsEditSession | None = None
|
|
59
|
+
self._busy = False
|
|
60
|
+
self._operation: asyncio.Task | None = None
|
|
61
|
+
self._search_focused = True
|
|
62
|
+
self._search_area = search_input(
|
|
63
|
+
lambda: i18n(message.config_search_placeholder)
|
|
64
|
+
)
|
|
65
|
+
self._search_area.buffer.on_text_changed += self._search_changed
|
|
66
|
+
self._content_window = Window(
|
|
67
|
+
FormattedTextControl(
|
|
68
|
+
self._content_fragments,
|
|
69
|
+
focusable=True,
|
|
70
|
+
get_cursor_position=self._cursor,
|
|
71
|
+
),
|
|
72
|
+
wrap_lines=False,
|
|
73
|
+
always_hide_cursor=True,
|
|
74
|
+
style="class:selection.body",
|
|
75
|
+
)
|
|
76
|
+
self._panel = MenuPanel(
|
|
77
|
+
header=self._header_fragments,
|
|
78
|
+
body=self._content_window,
|
|
79
|
+
footer=self._footer_fragments,
|
|
80
|
+
search=self._search_area,
|
|
81
|
+
show_search=lambda: True,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def enter(
|
|
85
|
+
self,
|
|
86
|
+
snapshot: ConfigSnapshot,
|
|
87
|
+
*,
|
|
88
|
+
runtime_read: Callable | None = None,
|
|
89
|
+
runtime_apply: Callable | None = None,
|
|
90
|
+
) -> None:
|
|
91
|
+
self._state = ConfigPickerState(snapshot)
|
|
92
|
+
self._session = SettingsEditSession(
|
|
93
|
+
snapshot, runtime_read=runtime_read, runtime_apply=runtime_apply
|
|
94
|
+
)
|
|
95
|
+
self._busy = False
|
|
96
|
+
self._search_focused = True
|
|
97
|
+
self._search_area.text = ""
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def container(self) -> HSplit:
|
|
101
|
+
return self._panel.container
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def search_area_window(self) -> Window:
|
|
105
|
+
return self._search_area.window
|
|
106
|
+
|
|
107
|
+
def focus_target(self) -> Window:
|
|
108
|
+
return self._panel.focus(self._search_focused)
|
|
109
|
+
|
|
110
|
+
def search_has_focus(self) -> bool:
|
|
111
|
+
return self._search_focused
|
|
112
|
+
|
|
113
|
+
def focus_search(self, active: bool = True) -> None:
|
|
114
|
+
self._search_focused = active
|
|
115
|
+
app = get_app_or_none()
|
|
116
|
+
if app is not None:
|
|
117
|
+
app.layout.focus(self.focus_target())
|
|
118
|
+
|
|
119
|
+
def inject_search_char(self, char: str) -> None:
|
|
120
|
+
self.focus_search()
|
|
121
|
+
self._search_area.buffer.insert_text(char)
|
|
122
|
+
|
|
123
|
+
def _search_changed(self, _buffer: Any) -> None:
|
|
124
|
+
if self._state:
|
|
125
|
+
self._state.filter(
|
|
126
|
+
self._search_area.text, {f: _field_label(f) for f in ConfigField}
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def handle_up(self) -> None:
|
|
130
|
+
if not self._state or self._search_focused:
|
|
131
|
+
return
|
|
132
|
+
if (
|
|
133
|
+
self._state.visible_fields
|
|
134
|
+
and self._state.focused_field == self._state.visible_fields[0]
|
|
135
|
+
):
|
|
136
|
+
self.focus_search()
|
|
137
|
+
else:
|
|
138
|
+
self._state.move(-1)
|
|
139
|
+
|
|
140
|
+
def handle_down(self) -> None:
|
|
141
|
+
if self._search_focused:
|
|
142
|
+
self.focus_search(False)
|
|
143
|
+
elif self._state:
|
|
144
|
+
self._state.move(1)
|
|
145
|
+
|
|
146
|
+
async def handle_tab(self) -> None:
|
|
147
|
+
if (
|
|
148
|
+
self._busy
|
|
149
|
+
or self._search_focused
|
|
150
|
+
or not self._state
|
|
151
|
+
or not self._state.visible_fields
|
|
152
|
+
or not self._session
|
|
153
|
+
):
|
|
154
|
+
return
|
|
155
|
+
self._busy = True
|
|
156
|
+
self._operation = asyncio.current_task()
|
|
157
|
+
try:
|
|
158
|
+
attribute = field_attribute(self._state.focused_field)
|
|
159
|
+
candidate = self._state.candidate()
|
|
160
|
+
if await self._session.change(attribute, getattr(candidate, attribute)):
|
|
161
|
+
self._state.current = self._session.current
|
|
162
|
+
self._state.last_save_error_messages = self._session.errors
|
|
163
|
+
finally:
|
|
164
|
+
self._busy = False
|
|
165
|
+
self._operation = None
|
|
166
|
+
|
|
167
|
+
def handle_enter(self) -> PickerExit | None:
|
|
168
|
+
if self._busy or not self._session:
|
|
169
|
+
return None
|
|
170
|
+
if self._search_focused:
|
|
171
|
+
self.focus_search(False)
|
|
172
|
+
return None
|
|
173
|
+
self._session.keep()
|
|
174
|
+
if self._state:
|
|
175
|
+
self._state.save_called = True
|
|
176
|
+
return PickerExit(PickerExitKind.SAVED)
|
|
177
|
+
|
|
178
|
+
async def handle_escape(self) -> PickerExit | None:
|
|
179
|
+
if self._busy:
|
|
180
|
+
return None
|
|
181
|
+
if self._search_focused:
|
|
182
|
+
if self._search_area.text:
|
|
183
|
+
self._search_area.text = ""
|
|
184
|
+
else:
|
|
185
|
+
self.focus_search(False)
|
|
186
|
+
return None
|
|
187
|
+
return await self.rollback()
|
|
188
|
+
|
|
189
|
+
async def rollback(self) -> PickerExit | None:
|
|
190
|
+
if not self._session or not self._session.active:
|
|
191
|
+
return PickerExit(PickerExitKind.CLEAN_EXIT)
|
|
192
|
+
self._busy = True
|
|
193
|
+
self._operation = asyncio.current_task()
|
|
194
|
+
try:
|
|
195
|
+
if await self._session.cancel():
|
|
196
|
+
return PickerExit(PickerExitKind.DISCARDED)
|
|
197
|
+
if self._state:
|
|
198
|
+
self._state.current = self._session.current
|
|
199
|
+
self._state.last_save_error_messages = self._session.errors
|
|
200
|
+
return None
|
|
201
|
+
finally:
|
|
202
|
+
self._busy = False
|
|
203
|
+
self._operation = None
|
|
204
|
+
|
|
205
|
+
async def rollback_before_exit(self) -> tuple[str, ...]:
|
|
206
|
+
if self._operation is not None:
|
|
207
|
+
await asyncio.shield(self._operation)
|
|
208
|
+
await self.rollback()
|
|
209
|
+
if self._session:
|
|
210
|
+
return self._session.errors + self._session.notices
|
|
211
|
+
return ()
|
|
212
|
+
|
|
213
|
+
def handle_ctrl_s(self) -> PickerExit | None:
|
|
214
|
+
# 保留旧快捷键作为显式接受剩余更改的入口,包含部分回滚失败的恢复路径。
|
|
215
|
+
if self._search_focused:
|
|
216
|
+
self.focus_search(False)
|
|
217
|
+
return self.handle_enter()
|
|
218
|
+
|
|
219
|
+
def take_result(self) -> tuple[bool, tuple[str, ...]]:
|
|
220
|
+
if not self._session or not self._state:
|
|
221
|
+
return False, ()
|
|
222
|
+
return self._state.save_called, self._session.errors + self._session.notices
|
|
223
|
+
|
|
224
|
+
def _header_fragments(self) -> list[tuple[str, str]]:
|
|
225
|
+
return [("class:selection.title", " Config")]
|
|
226
|
+
|
|
227
|
+
def _render_field_value(self, field: ConfigField, snapshot: ConfigSnapshot) -> str:
|
|
228
|
+
value = getattr(snapshot, field_attribute(field))
|
|
229
|
+
if field == ConfigField.MODEL_LEVEL:
|
|
230
|
+
return tier_name(value)
|
|
231
|
+
return str(value).lower() if isinstance(value, bool) else str(value)
|
|
232
|
+
|
|
233
|
+
def _main_fragments(self) -> list[tuple[str, str]]:
|
|
234
|
+
if not self._state:
|
|
235
|
+
return []
|
|
236
|
+
_, columns = terminal_size()
|
|
237
|
+
rows = []
|
|
238
|
+
for field in self._state.visible_fields:
|
|
239
|
+
value = self._render_field_value(field, self._state.current)
|
|
240
|
+
if field in RESTART_FIELDS:
|
|
241
|
+
value += " · " + i18n(message.config_restart_marker)
|
|
242
|
+
rows.extend(
|
|
243
|
+
setting_row(
|
|
244
|
+
_field_label(field),
|
|
245
|
+
value,
|
|
246
|
+
selected=field == self._state.focused_field,
|
|
247
|
+
columns=columns,
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
return rows or [
|
|
251
|
+
("class:selection.description", " " + i18n(message.menu_no_matches))
|
|
252
|
+
]
|
|
253
|
+
|
|
254
|
+
def _content_fragments(self) -> list[tuple[str, str]]:
|
|
255
|
+
return self._main_fragments()
|
|
256
|
+
|
|
257
|
+
def _cursor(self) -> Point:
|
|
258
|
+
_, columns = terminal_size()
|
|
259
|
+
return Point(
|
|
260
|
+
0,
|
|
261
|
+
MenuPanel.selected_line(self._main_fragments())
|
|
262
|
+
+ (1 if columns < 60 and self._state and self._state.visible_fields else 0),
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
def _footer_fragments(self) -> list[tuple[str, str]]:
|
|
266
|
+
if self._busy:
|
|
267
|
+
return [("class:selection.hint", " " + i18n(message.config_applying))]
|
|
268
|
+
if self._session and self._session.errors:
|
|
269
|
+
return [
|
|
270
|
+
("class:error", " " + " | ".join(self._session.errors) + "\n"),
|
|
271
|
+
("class:selection.hint", " " + i18n(message.config_rollback_hint)),
|
|
272
|
+
]
|
|
273
|
+
if self._search_focused:
|
|
274
|
+
return [("class:selection.hint", " " + i18n(message.config_search_hint))]
|
|
275
|
+
return [("class:selection.hint", " " + i18n(message.config_list_hint))]
|