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.
Files changed (534) hide show
  1. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/CONTEXT.md +72 -1
  2. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/PKG-INFO +2 -2
  3. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/animations.py +47 -0
  4. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/app.py +4 -0
  5. comate_cli-0.12.4b11/comate_cli/terminal_agent/config/edit_session.py +172 -0
  6. comate_cli-0.12.4b11/comate_cli/terminal_agent/config/picker.py +275 -0
  7. comate_cli-0.12.4b11/comate_cli/terminal_agent/config/picker_state.py +102 -0
  8. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config/store.py +118 -0
  9. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/event_renderer.py +85 -8
  10. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/__init__.py +3 -3
  11. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/_en.py +60 -0
  12. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/_ja.py +59 -0
  13. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/_zh.py +50 -0
  14. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/i18n/message.py +43 -0
  15. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/locale.py +4 -0
  16. comate_cli-0.12.4b11/comate_cli/terminal_agent/menu_panel.py +210 -0
  17. comate_cli-0.12.4b11/comate_cli/terminal_agent/plugins/marketplace_install_view.py +407 -0
  18. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/plugin_picker.py +110 -71
  19. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/installed_tab.py +94 -4
  20. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/marketplaces_tab.py +103 -78
  21. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/recap/controller.py +10 -0
  22. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/selection_menu.py +105 -83
  23. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/skill_slash_input.py +30 -3
  24. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/model.py +1 -1
  25. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/suggestion/controller.py +11 -1
  26. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/theme.py +4 -1
  27. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_fold.py +1 -1
  28. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_formatters.py +132 -15
  29. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/transcript_viewer.py +252 -77
  30. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui.py +59 -8
  31. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/btw_view.py +4 -47
  32. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/commands.py +199 -67
  33. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/input_behavior.py +23 -0
  34. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/key_bindings.py +85 -13
  35. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/mcp_connecting_view.py +25 -58
  36. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/pyproject.toml +7 -2
  37. comate_cli-0.12.4b11/tests/config/test_config_exit.py +131 -0
  38. comate_cli-0.12.4b11/tests/config/test_edit_session.py +260 -0
  39. comate_cli-0.12.4b11/tests/config/test_picker_state.py +65 -0
  40. comate_cli-0.12.4b11/tests/config/test_picker_ui.py +93 -0
  41. comate_cli-0.12.4b11/tests/config/test_runtime_settings.py +105 -0
  42. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/conftest.py +17 -0
  43. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/test_model.py +3 -3
  44. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/test_picker_state.py +1 -1
  45. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/test_store.py +2 -2
  46. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_next_step_suggestion_render.py +25 -2
  47. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_tab_accepts_next_step_suggestion.py +22 -4
  48. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_ctrl_b.py +3 -0
  49. comate_cli-0.12.4b11/tests/test_event_renderer_budget_floor.py +189 -0
  50. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_installed_tab.py +323 -2
  51. comate_cli-0.12.4b11/tests/test_loading_line_fragments.py +116 -0
  52. comate_cli-0.12.4b11/tests/test_marketplace_add_commands.py +149 -0
  53. comate_cli-0.12.4b11/tests/test_marketplace_install_view.py +258 -0
  54. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_marketplaces_tab.py +257 -100
  55. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_slash_command.py +20 -0
  56. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_menu_cursor_unification.py +9 -7
  57. comate_cli-0.12.4b11/tests/test_menu_panel.py +229 -0
  58. comate_cli-0.12.4b11/tests/test_menu_panel_pty.py +119 -0
  59. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_tui_components.py +80 -71
  60. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_v4_stdio_smoke.py +1 -0
  61. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_shell_mode.py +3 -0
  62. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_skill_slash_input.py +177 -22
  63. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar.py +12 -1
  64. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_theme.py +3 -2
  65. comate_cli-0.12.4b11/tests/test_tool_call_protection.py +99 -0
  66. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_fold_panel.py +30 -25
  67. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_formatters.py +18 -0
  68. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_state.py +1 -1
  69. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_view.py +4 -2
  70. comate_cli-0.12.4b11/tests/test_transcript_viewer.py +606 -0
  71. comate_cli-0.12.4b11/tests/test_transcript_viewer_record_matching.py +130 -0
  72. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_transcript_viewer_tool_fold.py +35 -4
  73. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_queue_sdk_source.py +61 -1
  74. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_surrogate_repair.py +1 -0
  75. comate_cli-0.12.4b11/tools/transcript_viewer_bench.py +250 -0
  76. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/uv.lock +27 -2
  77. comate_cli-0.12.4b9/comate_cli/terminal_agent/config/picker.py +0 -252
  78. comate_cli-0.12.4b9/comate_cli/terminal_agent/config/picker_state.py +0 -245
  79. comate_cli-0.12.4b9/comate_cli/terminal_agent/plugins/marketplace_install_view.py +0 -285
  80. comate_cli-0.12.4b9/tests/config/test_picker_state.py +0 -300
  81. comate_cli-0.12.4b9/tests/config/test_picker_ui.py +0 -147
  82. comate_cli-0.12.4b9/tests/test_transcript_viewer.py +0 -249
  83. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/bash/3b0c312b1a234220818cb8cc15a12ea1565c69dc5f828351a492dab1add0cf84.txt +0 -0
  84. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/bash/b0696d5d44fdde7597b8e9bd706d61237290ebca0c1c99273799393a7af99316.txt +0 -0
  85. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/bash/e1164ab5f5f1e125db38bb44420532265c958f19533fbda8700db5a8aa4c3d68.txt +0 -0
  86. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/00f8013ce28fed8e3076db6490d6a3de8dbc1f57f5248a1f5e2710f11ab6849c.txt +0 -0
  87. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/0a5f3319bc1813a523b8d041831399f3ea694fcdb96f4b1df740300d08c60521.txt +0 -0
  88. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/17dc19a9b5faddcd056013e7783c8d23525d060b7b20a73ee241c569bedea6d8.txt +0 -0
  89. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/2b488f719c3431607773d9cebef4924ebfa33745adc68d8ee0f89596c608a218.txt +0 -0
  90. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/32ce175150a77180dda04a76ea66b9ee5b0c46ea0fd0842172bacece964d57a4.txt +0 -0
  91. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/43166c9eb998d1a426ce0c014348e39adc8c8e1d3d7a94ced4cc33ab268ecdeb.txt +0 -0
  92. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/4afc47414280761b7c94ff91f7477c4eb5602396da89303b403c6f3ef9535fd0.txt +0 -0
  93. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/56fca6c3112743a94cd0df58e04ee6dda31546ed53d50f8bf907dccb6f5329d3.txt +0 -0
  94. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/605fcb1ca26d1cb632e364dd044d280a12ad4f188db698d5bad57fe1ff556ce3.txt +0 -0
  95. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/6763a04477b314da76472e76696c8b03ee89fffc23ce74a22c634ea373840acd.txt +0 -0
  96. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/6d1856ff719ee695ed9205cf68723a263f8c70fe090295037c1c9a837f8eac13.txt +0 -0
  97. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/6e08c59431a214d8c3650a701cbaaf9125503d59d28476642f8b5a0ad6c8ed93.txt +0 -0
  98. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/746f6a3b34e30583972816a0052d99e8297096ba522d66027b085e3a0069b7db.txt +0 -0
  99. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/7c8fa2270ca7721e8619ba7eaec744100877330317dd5e8a1e42494a09579317.txt +0 -0
  100. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/7cc3e32a61277dc3e35039fdc1cac3691e147cd50d8d16fa75447de7d11abb77.txt +0 -0
  101. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/8203d4eaf35b0bb224cb12067e638b7f873ae0af05a590adedc02ae159a08099.txt +0 -0
  102. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/82a7ce335091c00f8aee0ff54b6a75ed25fb6f7a2f4bf8d29921c3f2704ada81.txt +0 -0
  103. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/82e9a29128ad224555ae0e85dddcc118d92a8f4faf4c8a3c3702c6b43dc71511.txt +0 -0
  104. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/83be41699a979e16de16f3095981346f337fda56a3c254420df953e2de87d982.txt +0 -0
  105. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/84074b6fda0e110d23094926c0d1846130be2b3870b1bcd5516243bae808b209.txt +0 -0
  106. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/a92368734a2d79c15eaba1c7d282bab2d4150ccde0e41e30628cfb6b7be6a678.txt +0 -0
  107. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/b02349374e026c124a60335b4b0e77698e4b7f8391f2466c827f6f80a8d596b2.txt +0 -0
  108. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/b41279d93d2b1f03e99bf2fdcd4477781edf3546256489e2d37f082fa414ef94.txt +0 -0
  109. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/bde0cfc02d38109cc02a28dd07611e464db9b47fef8b16fc25591866e5003316.txt +0 -0
  110. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/c0e234da2bfe338ffbce547372af90d36ce7580361b69664823d12fac048a86e.txt +0 -0
  111. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/c979b9589e166ae451c819fc8fc1efdf9eb042ce7af99e420a5b540f0d041a7a.txt +0 -0
  112. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/dd39676b55965a3e04c1b28c82cd9c15e335776f39f325f61854d3e48aa87859.txt +0 -0
  113. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/dec1ee9f38d117f649d0ba2cfb54b50d9ccd841833170c49614fa181a358013e.txt +0 -0
  114. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/eac0d88d65c24b10af556c030b795f3312cc70fc80f8f64575205ea1a6476264.txt +0 -0
  115. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/ef063804b585209aafbded7c27ad8d5eacbad17b3bb967022290a9efd01f6d13.txt +0 -0
  116. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/f75a98ad1ac3c085060f90492292060b3720dfa98c776e61a643b9824d1dc237.txt +0 -0
  117. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/faffcd8b4abd87e4abff3b72dcde673e844a4d7e230fbcc5c116ddd11815c37b.txt +0 -0
  118. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/fb29e07995891317ca0daa3257e541238908889bc7a68efeba695c8ac3a2db86.txt +0 -0
  119. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/grep_content/feed470ec463825f43ae4e1b92a5996b1dbad91605fe491f39c9ee60879b7155.txt +0 -0
  120. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/index.json +0 -0
  121. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/ls/5a0a29a96857998fdfe5696c09b9c60027a6529e21108e22a20f5227afeddb59.json +0 -0
  122. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/1f093e98c0f4026921bb2df0c7c04d6b55b51ec40c9fbf38ba57bd387399127d.txt +0 -0
  123. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/57c31009cc3665a6a672811ecf048cfb75ff7bae92598df943f492c53d39ca8e.txt +0 -0
  124. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/916a2e47f13fd22d3a73a4896c7a5edb3381b8a2c8322ce3ab8a4bf9da94c4a0.txt +0 -0
  125. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/91f5872f5b4b1b43f16589f7dd25e47236a805e848b37307cef464e881307fe1.txt +0 -0
  126. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/9871dc91ff9afef1303c74cf669996828a7db3dbff6c4c41fbac0a53fd7d195b.txt +0 -0
  127. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/af594562a5579ffc9bef105dc77ed26408b2408447005046c9c6505541e2776a.txt +0 -0
  128. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/c52ec3da48b3a731ed42cc357258a4627d2d11fab5ef14d3050fd50e748151d4.txt +0 -0
  129. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/f8c08a56feb0812b35a8e4b29a721d38c0aacd83ce3620c432d8b52114c14816.txt +0 -0
  130. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/artifacts/tool_result/fa30187a59d255f168806ee0de7a0a32b00535e53e7c5420aad1bac44b54a667.txt +0 -0
  131. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.agent/scheduled_prompts.json +0 -0
  132. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/.gitignore +0 -0
  133. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/CHANGELOG.md +0 -0
  134. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/README.md +0 -0
  135. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/__init__.py +0 -0
  136. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/__main__.py +0 -0
  137. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/device_identity.py +0 -0
  138. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/distribution.py +0 -0
  139. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/main.py +0 -0
  140. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/mcp_cli.py +0 -0
  141. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/__init__.py +0 -0
  142. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/approval_bridge.py +0 -0
  143. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/approval_content_preview.py +0 -0
  144. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/assistant_render.py +0 -0
  145. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/__init__.py +0 -0
  146. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/announcements.py +0 -0
  147. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/client.py +0 -0
  148. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/feedback.py +0 -0
  149. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/provider_snapshot.py +0 -0
  150. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/rating.py +0 -0
  151. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/runtime.py +0 -0
  152. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/session_report.py +0 -0
  153. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/session_title.py +0 -0
  154. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/backend/tasks.py +0 -0
  155. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/bash_command_display.py +0 -0
  156. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/.keep +0 -0
  157. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/commit.md +0 -0
  158. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/implement-plan.md +0 -0
  159. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/learn.md +0 -0
  160. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/builtin_commands/open-pr.md +0 -0
  161. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/clipboard_image.py +0 -0
  162. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/codenames.py +0 -0
  163. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config/__init__.py +0 -0
  164. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config/model.py +0 -0
  165. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/config_check.py +0 -0
  166. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/console_profile.py +0 -0
  167. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/context_view.py +0 -0
  168. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/custom_slash_commands.py +0 -0
  169. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/effort_menu.py +0 -0
  170. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/effort_ruler.py +0 -0
  171. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/effort_style.py +0 -0
  172. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/env_utils.py +0 -0
  173. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/error_display.py +0 -0
  174. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/exit_confirm_view.py +0 -0
  175. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/exit_watchdog.py +0 -0
  176. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/figures.py +0 -0
  177. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/file_ref_hint.py +0 -0
  178. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/fragment_utils.py +0 -0
  179. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/goal_edit_view.py +0 -0
  180. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/goal_resume_view.py +0 -0
  181. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/history_printer.py +0 -0
  182. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/image_chips.py +0 -0
  183. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/input_geometry.py +0 -0
  184. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/jobs_picker.py +0 -0
  185. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/jobs_state.py +0 -0
  186. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/layout_coordinator.py +0 -0
  187. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/logging_adapter.py +0 -0
  188. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/logging_file_handler.py +0 -0
  189. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/logo.py +0 -0
  190. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/markdown_render.py +0 -0
  191. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/mcp_serve.py +0 -0
  192. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/mention_completer.py +0 -0
  193. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/message_style.py +0 -0
  194. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/model_tier_style.py +0 -0
  195. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/models.py +0 -0
  196. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/output_style_menu.py +0 -0
  197. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/__init__.py +0 -0
  198. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/auto_update_runner.py +0 -0
  199. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/auto_update_store.py +0 -0
  200. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/__init__.py +0 -0
  201. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/detail_view.py +0 -0
  202. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/plugin_list.py +0 -0
  203. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/search_box.py +0 -0
  204. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/components/tab_bar.py +0 -0
  205. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/operation_state.py +0 -0
  206. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/__init__.py +0 -0
  207. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/discover_tab.py +0 -0
  208. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/plugins/tabs/errors_tab.py +0 -0
  209. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/preflight.py +0 -0
  210. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/preflight_wizard.py +0 -0
  211. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/preflight_wizard_ui.py +0 -0
  212. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/print_mode.py +0 -0
  213. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/question_broker.py +0 -0
  214. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/question_view.py +0 -0
  215. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/recap/__init__.py +0 -0
  216. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/resume_picker.py +0 -0
  217. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/resume_preview.py +0 -0
  218. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/resume_selector.py +0 -0
  219. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_commands.py +0 -0
  220. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_relay.py +0 -0
  221. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_stdio.py +0 -0
  222. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/rpc_ws.py +0 -0
  223. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/scm_request_status.py +0 -0
  224. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/side_install.py +0 -0
  225. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/sigint_guard.py +0 -0
  226. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/skills_menu.py +0 -0
  227. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/slash_commands.py +0 -0
  228. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/startup.py +0 -0
  229. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/startup_profile.py +0 -0
  230. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/status_bar.py +0 -0
  231. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/__init__.py +0 -0
  232. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/picker.py +0 -0
  233. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/picker_state.py +0 -0
  234. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/statusline/store.py +0 -0
  235. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/stream_pacer.py +0 -0
  236. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/suggestion/__init__.py +0 -0
  237. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/synchronized_output.py +0 -0
  238. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/text_effects.py +0 -0
  239. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tips.py +0 -0
  240. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_approval_view.py +0 -0
  241. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_fold_view.py +0 -0
  242. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_state.py +0 -0
  243. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_store.py +0 -0
  244. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_result_viewer.py +0 -0
  245. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tool_view.py +0 -0
  246. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/__init__.py +0 -0
  247. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/approval_queue.py +0 -0
  248. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/history_sync.py +0 -0
  249. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/render_panels.py +0 -0
  250. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/resize_guard.py +0 -0
  251. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/run_clock.py +0 -0
  252. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/shell_mode.py +0 -0
  253. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/slash_command_registry.py +0 -0
  254. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/tui_parts/ui_mode.py +0 -0
  255. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/ultracode_keyword.py +0 -0
  256. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/update_check.py +0 -0
  257. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/update_messages.py +0 -0
  258. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/workflows_panel.py +0 -0
  259. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_agent/workflows_panel_model.py +0 -0
  260. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/terminal_title.py +0 -0
  261. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/comate_cli/update_cli.py +0 -0
  262. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/cli-rpc-stdio-guide.md +0 -0
  263. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/release-notes/0.12.3.md +0 -0
  264. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/startup-performance.md +0 -0
  265. {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
  266. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/docs/superpowers/plans/2026-07-07-windows-update-manual-rollback.md +0 -0
  267. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/_fake_anthropic_server.py +0 -0
  268. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/_rpc_ws_client.py +0 -0
  269. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/__init__.py +0 -0
  270. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_model.py +0 -0
  271. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_roundtrip.py +0 -0
  272. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_skills_denylist_migration.py +0 -0
  273. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_store_load.py +0 -0
  274. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/config/test_store_save.py +0 -0
  275. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/fixtures/exit_watchdog_child.py +0 -0
  276. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/fixtures/fake_mcp_misbehaving_stdout.py +0 -0
  277. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/recap/test_idle_recap_controller.py +0 -0
  278. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/recap/test_recap_history_rendering.py +0 -0
  279. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/recap/test_tui_idle_recap_integration.py +0 -0
  280. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/statusline/__init__.py +0 -0
  281. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_next_step_suggestion_controller.py +0 -0
  282. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/suggestion/test_tui_next_step_suggestion_integration.py +0 -0
  283. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_animations_styles.py +0 -0
  284. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_animator_shuffle.py +0 -0
  285. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_config_check_gate.py +0 -0
  286. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_exit_lifecycle.py +0 -0
  287. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_mcp_preload.py +0 -0
  288. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_mcp_preload_kick.py +0 -0
  289. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_preflight_gate.py +0 -0
  290. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_print_mode.py +0 -0
  291. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_profile_threading.py +0 -0
  292. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_ctrl_c_exit.py +0 -0
  293. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_shell_mode.py +0 -0
  294. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_pty_smoke.py +0 -0
  295. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_shutdown.py +0 -0
  296. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_startup_latency.py +0 -0
  297. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_startup_order.py +0 -0
  298. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_token_cost_config.py +0 -0
  299. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_app_usage_line.py +0 -0
  300. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_approval_bridge.py +0 -0
  301. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_approval_content_preview.py +0 -0
  302. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_announcements.py +0 -0
  303. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_client.py +0 -0
  304. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_feedback.py +0 -0
  305. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_provider_snapshot.py +0 -0
  306. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_rating.py +0 -0
  307. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_session_report.py +0 -0
  308. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_backend_tasks.py +0 -0
  309. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_btw_slash_command.py +0 -0
  310. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_busy_slash_gating.py +0 -0
  311. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_cli_project_root.py +0 -0
  312. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_clipboard_image_reader.py +0 -0
  313. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_commands_system_messages.py +0 -0
  314. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_compact_command_semantics.py +0 -0
  315. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_completion_context_activation.py +0 -0
  316. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_completion_status_panel.py +0 -0
  317. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_config_check.py +0 -0
  318. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_console_profile.py +0 -0
  319. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_context_command.py +0 -0
  320. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_context_view.py +0 -0
  321. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ctrl_b_background.py +0 -0
  322. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ctrl_c_clear_input.py +0 -0
  323. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_custom_slash_commands.py +0 -0
  324. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_device_identity.py +0 -0
  325. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_discover_tab.py +0 -0
  326. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_distribution_contract.py +0 -0
  327. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_drain_frame_atomicity.py +0 -0
  328. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_menu.py +0 -0
  329. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_menu_frame_rate.py +0 -0
  330. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_ruler.py +0 -0
  331. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_slash_command.py +0 -0
  332. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_effort_style.py +0 -0
  333. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_errors_tab.py +0 -0
  334. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer.py +0 -0
  335. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_approval_wait.py +0 -0
  336. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_boundary.py +0 -0
  337. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_e2e.py +0 -0
  338. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_fixed_overhead.py +0 -0
  339. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_idle_prune.py +0 -0
  340. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_jobs.py +0 -0
  341. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_log_boundary.py +0 -0
  342. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_log_queue.py +0 -0
  343. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_provider_overflow.py +0 -0
  344. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_shell.py +0 -0
  345. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_stream_pacing.py +0 -0
  346. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_stream_staging.py +0 -0
  347. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_streaming.py +0 -0
  348. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_tool_args_progress.py +0 -0
  349. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_event_renderer_tool_fold.py +0 -0
  350. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_confirm_view.py +0 -0
  351. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_guard.py +0 -0
  352. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_watchdog.py +0 -0
  353. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_exit_watchdog_subprocess.py +0 -0
  354. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_file_ref_hint.py +0 -0
  355. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_format_error.py +0 -0
  356. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_edit_handlers.py +0 -0
  357. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_edit_view.py +0 -0
  358. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_paused_hint.py +0 -0
  359. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_resume_tui.py +0 -0
  360. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_resume_view.py +0 -0
  361. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_goal_slash_command.py +0 -0
  362. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_handle_error.py +0 -0
  363. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_drain_throttle.py +0 -0
  364. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer.py +0 -0
  365. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_log.py +0 -0
  366. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_styles.py +0 -0
  367. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_subtitle_position.py +0 -0
  368. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_printer_tool_fold.py +0 -0
  369. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_sync.py +0 -0
  370. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_history_sync_tool_fold.py +0 -0
  371. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_i18n.py +0 -0
  372. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_image_chips.py +0 -0
  373. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_image_preprocess_offload_lag.py +0 -0
  374. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_import_weight.py +0 -0
  375. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_input_behavior.py +0 -0
  376. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_input_history.py +0 -0
  377. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_input_separator_counter.py +0 -0
  378. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_interrupt_exit_semantics.py +0 -0
  379. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_jobs_panel.py +0 -0
  380. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_jobs_picker.py +0 -0
  381. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_key_bindings_system_messages.py +0 -0
  382. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_layout_coordinator.py +0 -0
  383. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_loading_modal_suppression.py +0 -0
  384. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_loading_tip_picker.py +0 -0
  385. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_logging_adapter.py +0 -0
  386. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_logging_file_handler.py +0 -0
  387. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_logo.py +0 -0
  388. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_main_args.py +0 -0
  389. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_main_args_yolo.py +0 -0
  390. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_main_profile_entry.py +0 -0
  391. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_markdown_render.py +0 -0
  392. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_cli.py +0 -0
  393. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_cli_scope_defaults.py +0 -0
  394. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mcp_serve.py +0 -0
  395. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_mention_completer.py +0 -0
  396. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_message_style.py +0 -0
  397. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_modal_freeze_timing.py +0 -0
  398. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_modal_panel_visibility.py +0 -0
  399. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_model_switch_command.py +0 -0
  400. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_model_tier_style.py +0 -0
  401. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_no_raw_colors.py +0 -0
  402. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_output_style_slash_command.py +0 -0
  403. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_permission_mode_cycle.py +0 -0
  404. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_auto_update_runner.py +0 -0
  405. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_auto_update_store.py +0 -0
  406. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_auto_update_tui.py +0 -0
  407. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_operation_state.py +0 -0
  408. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_plugin_slash_commands.py +0 -0
  409. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_preflight.py +0 -0
  410. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_preflight_copilot.py +0 -0
  411. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_preflight_wizard_ui.py +0 -0
  412. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_pty_output_integrity.py +0 -0
  413. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_question_broker.py +0 -0
  414. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_question_key_bindings.py +0 -0
  415. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_question_view.py +0 -0
  416. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resize_guard.py +0 -0
  417. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_picker.py +0 -0
  418. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_picker_exit_safety.py +0 -0
  419. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_preview.py +0 -0
  420. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_resume_selector.py +0 -0
  421. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rewind_command_semantics.py +0 -0
  422. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_mode_logging.py +0 -0
  423. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_relay_dial_out.py +0 -0
  424. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_relay_e2e_smoke.py +0 -0
  425. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_relay_process_smoke.py +0 -0
  426. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_v4_ws_smoke.py +0 -0
  427. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_rpc_ws_bind_failure.py +0 -0
  428. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_run_clock.py +0 -0
  429. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_running_tool_status_line.py +0 -0
  430. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_scm_request_status.py +0 -0
  431. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_scrollback_write_encoding.py +0 -0
  432. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_selection_menu.py +0 -0
  433. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_session_auto_title.py +0 -0
  434. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_session_query_token_summary.py +0 -0
  435. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_settings_write_guard.py +0 -0
  436. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_shutdown_noise_guard.py +0 -0
  437. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_shutdown_noise_integration.py +0 -0
  438. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_side_install.py +0 -0
  439. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_sigint_guard.py +0 -0
  440. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_sigint_key_binding.py +0 -0
  441. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_skills_slash_command.py +0 -0
  442. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_add_dir.py +0 -0
  443. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_argument_hint.py +0 -0
  444. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_clear.py +0 -0
  445. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_completer.py +0 -0
  446. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_slash_registry.py +0 -0
  447. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_startup_import_budget.py +0 -0
  448. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_startup_profile.py +0 -0
  449. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar_mid_turn_refresh.py +0 -0
  450. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar_request_status.py +0 -0
  451. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_status_bar_transient.py +0 -0
  452. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_stream_pacer.py +0 -0
  453. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_stream_pacing_tick.py +0 -0
  454. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_stream_staging_panel.py +0 -0
  455. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_style_class_coverage.py +0 -0
  456. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_synchronized_output.py +0 -0
  457. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tab_title.py +0 -0
  458. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_panel_format.py +0 -0
  459. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_panel_key_bindings.py +0 -0
  460. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_panel_rendering.py +0 -0
  461. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_task_poll.py +0 -0
  462. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_terminal_title.py +0 -0
  463. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tips.py +0 -0
  464. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_todo_panel_busy_gating.py +0 -0
  465. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_key_bindings.py +0 -0
  466. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_tui.py +0 -0
  467. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_view.py +0 -0
  468. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_approval_view_workflow.py +0 -0
  469. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_fold.py +0 -0
  470. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_fold_view.py +0 -0
  471. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_store.py +0 -0
  472. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_viewer.py +0 -0
  473. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_result_viewer_key_bindings.py +0 -0
  474. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tool_view_styles.py +0 -0
  475. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_builtin_slash_chain.py +0 -0
  476. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_deferred_prewarm.py +0 -0
  477. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_elapsed_status.py +0 -0
  478. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_esc_queue.py +0 -0
  479. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_exit_idempotence.py +0 -0
  480. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_exit_paced_tail.py +0 -0
  481. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_exit_pending_logs.py +0 -0
  482. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_hot_reload.py +0 -0
  483. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_chip_seed.py +0 -0
  484. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_paste.py +0 -0
  485. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_path_upgrade.py +0 -0
  486. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_restore.py +0 -0
  487. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_image_submit.py +0 -0
  488. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_interrupt_queue_recall.py +0 -0
  489. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_llm_retry_panel.py +0 -0
  490. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_loading_tip_rotation.py +0 -0
  491. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_local_interactive_barrier.py +0 -0
  492. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_mcp_init_gate.py +0 -0
  493. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_paste_history_persistence.py +0 -0
  494. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_paste_newline_guard.py +0 -0
  495. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_paste_placeholder.py +0 -0
  496. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_plugin_load.py +0 -0
  497. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_provider_error_shield.py +0 -0
  498. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_queue_pop_images.py +0 -0
  499. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_queue_preview.py +0 -0
  500. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_replace_session_resume_hint.py +0 -0
  501. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_scheduled_fire_log.py +0 -0
  502. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_scratchpad_fold_wiring.py +0 -0
  503. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_send_undo_window.py +0 -0
  504. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_session_observers.py +0 -0
  505. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_shutdown_cancel_propagation.py +0 -0
  506. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_split_invariance.py +0 -0
  507. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_startup_latency.py +0 -0
  508. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_thinking_display.py +0 -0
  509. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_tool_result_registry_lifecycle.py +0 -0
  510. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_tui_window_too_small_fallback.py +0 -0
  511. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ui_mode_derivation.py +0 -0
  512. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ui_tick_exception_isolation.py +0 -0
  513. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_keyword.py +0 -0
  514. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_keyword_frame_rate.py +0 -0
  515. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_keyword_submit.py +0 -0
  516. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_ultracode_shimmer_render.py +0 -0
  517. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_update_check.py +0 -0
  518. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_update_cli.py +0 -0
  519. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_upstream_surrogate_merge_characterization.py +0 -0
  520. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_usage_command.py +0 -0
  521. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_wellformed_terminal_input.py +0 -0
  522. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_whitelabel_clear_logo.py +0 -0
  523. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_windows_sigint_console.py +0 -0
  524. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_workflows_panel.py +0 -0
  525. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_workflows_panel_model.py +0 -0
  526. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_wrap_user_text.py +0 -0
  527. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tests/test_zipapp_launcher_path.py +0 -0
  528. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/diagnose_windows_shim_rename.py +0 -0
  529. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/logo_lab.py +0 -0
  530. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/nico_preview.py +0 -0
  531. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/probe_conhost_char_width.py +0 -0
  532. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/probe_conhost_render_replay.py +0 -0
  533. {comate_cli-0.12.4b9 → comate_cli-0.12.4b11}/tools/startup_bench.py +0 -0
  534. {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.4b9
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.16
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))]