comate-cli 0.12.4b6__tar.gz → 0.12.4b8__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 (508) hide show
  1. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/CHANGELOG.md +6 -0
  2. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/PKG-INFO +2 -2
  3. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/event_renderer.py +16 -0
  4. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/i18n/_en.py +12 -0
  5. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/i18n/_ja.py +12 -0
  6. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/i18n/_zh.py +11 -0
  7. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/i18n/message.py +9 -0
  8. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/skills_menu.py +26 -10
  9. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tips.py +8 -3
  10. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/commands.py +203 -24
  11. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/render_panels.py +9 -6
  12. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/pyproject.toml +2 -2
  13. comate_cli-0.12.4b8/tests/test_event_renderer_idle_prune.py +51 -0
  14. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_mcp_slash_command.py +488 -0
  15. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_skills_slash_command.py +54 -5
  16. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_task_panel_rendering.py +10 -4
  17. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tips.py +15 -0
  18. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/uv.lock +2 -2
  19. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/bash/3b0c312b1a234220818cb8cc15a12ea1565c69dc5f828351a492dab1add0cf84.txt +0 -0
  20. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/bash/b0696d5d44fdde7597b8e9bd706d61237290ebca0c1c99273799393a7af99316.txt +0 -0
  21. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/bash/e1164ab5f5f1e125db38bb44420532265c958f19533fbda8700db5a8aa4c3d68.txt +0 -0
  22. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/00f8013ce28fed8e3076db6490d6a3de8dbc1f57f5248a1f5e2710f11ab6849c.txt +0 -0
  23. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/0a5f3319bc1813a523b8d041831399f3ea694fcdb96f4b1df740300d08c60521.txt +0 -0
  24. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/17dc19a9b5faddcd056013e7783c8d23525d060b7b20a73ee241c569bedea6d8.txt +0 -0
  25. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/2b488f719c3431607773d9cebef4924ebfa33745adc68d8ee0f89596c608a218.txt +0 -0
  26. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/32ce175150a77180dda04a76ea66b9ee5b0c46ea0fd0842172bacece964d57a4.txt +0 -0
  27. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/43166c9eb998d1a426ce0c014348e39adc8c8e1d3d7a94ced4cc33ab268ecdeb.txt +0 -0
  28. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/4afc47414280761b7c94ff91f7477c4eb5602396da89303b403c6f3ef9535fd0.txt +0 -0
  29. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/56fca6c3112743a94cd0df58e04ee6dda31546ed53d50f8bf907dccb6f5329d3.txt +0 -0
  30. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/605fcb1ca26d1cb632e364dd044d280a12ad4f188db698d5bad57fe1ff556ce3.txt +0 -0
  31. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/6763a04477b314da76472e76696c8b03ee89fffc23ce74a22c634ea373840acd.txt +0 -0
  32. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/6d1856ff719ee695ed9205cf68723a263f8c70fe090295037c1c9a837f8eac13.txt +0 -0
  33. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/6e08c59431a214d8c3650a701cbaaf9125503d59d28476642f8b5a0ad6c8ed93.txt +0 -0
  34. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/746f6a3b34e30583972816a0052d99e8297096ba522d66027b085e3a0069b7db.txt +0 -0
  35. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/7c8fa2270ca7721e8619ba7eaec744100877330317dd5e8a1e42494a09579317.txt +0 -0
  36. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/7cc3e32a61277dc3e35039fdc1cac3691e147cd50d8d16fa75447de7d11abb77.txt +0 -0
  37. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/8203d4eaf35b0bb224cb12067e638b7f873ae0af05a590adedc02ae159a08099.txt +0 -0
  38. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/82a7ce335091c00f8aee0ff54b6a75ed25fb6f7a2f4bf8d29921c3f2704ada81.txt +0 -0
  39. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/82e9a29128ad224555ae0e85dddcc118d92a8f4faf4c8a3c3702c6b43dc71511.txt +0 -0
  40. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/83be41699a979e16de16f3095981346f337fda56a3c254420df953e2de87d982.txt +0 -0
  41. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/84074b6fda0e110d23094926c0d1846130be2b3870b1bcd5516243bae808b209.txt +0 -0
  42. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/a92368734a2d79c15eaba1c7d282bab2d4150ccde0e41e30628cfb6b7be6a678.txt +0 -0
  43. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/b02349374e026c124a60335b4b0e77698e4b7f8391f2466c827f6f80a8d596b2.txt +0 -0
  44. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/b41279d93d2b1f03e99bf2fdcd4477781edf3546256489e2d37f082fa414ef94.txt +0 -0
  45. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/bde0cfc02d38109cc02a28dd07611e464db9b47fef8b16fc25591866e5003316.txt +0 -0
  46. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/c0e234da2bfe338ffbce547372af90d36ce7580361b69664823d12fac048a86e.txt +0 -0
  47. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/c979b9589e166ae451c819fc8fc1efdf9eb042ce7af99e420a5b540f0d041a7a.txt +0 -0
  48. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/dd39676b55965a3e04c1b28c82cd9c15e335776f39f325f61854d3e48aa87859.txt +0 -0
  49. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/dec1ee9f38d117f649d0ba2cfb54b50d9ccd841833170c49614fa181a358013e.txt +0 -0
  50. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/eac0d88d65c24b10af556c030b795f3312cc70fc80f8f64575205ea1a6476264.txt +0 -0
  51. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/ef063804b585209aafbded7c27ad8d5eacbad17b3bb967022290a9efd01f6d13.txt +0 -0
  52. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/f75a98ad1ac3c085060f90492292060b3720dfa98c776e61a643b9824d1dc237.txt +0 -0
  53. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/faffcd8b4abd87e4abff3b72dcde673e844a4d7e230fbcc5c116ddd11815c37b.txt +0 -0
  54. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/fb29e07995891317ca0daa3257e541238908889bc7a68efeba695c8ac3a2db86.txt +0 -0
  55. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/grep_content/feed470ec463825f43ae4e1b92a5996b1dbad91605fe491f39c9ee60879b7155.txt +0 -0
  56. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/index.json +0 -0
  57. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/ls/5a0a29a96857998fdfe5696c09b9c60027a6529e21108e22a20f5227afeddb59.json +0 -0
  58. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/1f093e98c0f4026921bb2df0c7c04d6b55b51ec40c9fbf38ba57bd387399127d.txt +0 -0
  59. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/57c31009cc3665a6a672811ecf048cfb75ff7bae92598df943f492c53d39ca8e.txt +0 -0
  60. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/916a2e47f13fd22d3a73a4896c7a5edb3381b8a2c8322ce3ab8a4bf9da94c4a0.txt +0 -0
  61. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/91f5872f5b4b1b43f16589f7dd25e47236a805e848b37307cef464e881307fe1.txt +0 -0
  62. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/9871dc91ff9afef1303c74cf669996828a7db3dbff6c4c41fbac0a53fd7d195b.txt +0 -0
  63. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/af594562a5579ffc9bef105dc77ed26408b2408447005046c9c6505541e2776a.txt +0 -0
  64. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/c52ec3da48b3a731ed42cc357258a4627d2d11fab5ef14d3050fd50e748151d4.txt +0 -0
  65. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/f8c08a56feb0812b35a8e4b29a721d38c0aacd83ce3620c432d8b52114c14816.txt +0 -0
  66. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/artifacts/tool_result/fa30187a59d255f168806ee0de7a0a32b00535e53e7c5420aad1bac44b54a667.txt +0 -0
  67. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.agent/scheduled_prompts.json +0 -0
  68. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/.gitignore +0 -0
  69. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/CONTEXT.md +0 -0
  70. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/README.md +0 -0
  71. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/__init__.py +0 -0
  72. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/__main__.py +0 -0
  73. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/device_identity.py +0 -0
  74. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/distribution.py +0 -0
  75. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/main.py +0 -0
  76. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/mcp_cli.py +0 -0
  77. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/__init__.py +0 -0
  78. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/animations.py +0 -0
  79. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/app.py +0 -0
  80. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/approval_bridge.py +0 -0
  81. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/approval_content_preview.py +0 -0
  82. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/assistant_render.py +0 -0
  83. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/__init__.py +0 -0
  84. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/announcements.py +0 -0
  85. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/client.py +0 -0
  86. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/feedback.py +0 -0
  87. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/provider_snapshot.py +0 -0
  88. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/rating.py +0 -0
  89. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/runtime.py +0 -0
  90. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/session_report.py +0 -0
  91. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/session_title.py +0 -0
  92. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/backend/tasks.py +0 -0
  93. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/bash_command_display.py +0 -0
  94. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/builtin_commands/.keep +0 -0
  95. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/builtin_commands/commit.md +0 -0
  96. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/builtin_commands/implement-plan.md +0 -0
  97. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/builtin_commands/learn.md +0 -0
  98. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/builtin_commands/pr.md +0 -0
  99. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/clipboard_image.py +0 -0
  100. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/codenames.py +0 -0
  101. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/config/__init__.py +0 -0
  102. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/config/model.py +0 -0
  103. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/config/picker.py +0 -0
  104. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/config/picker_state.py +0 -0
  105. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/config/store.py +0 -0
  106. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/config_check.py +0 -0
  107. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/console_profile.py +0 -0
  108. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/context_view.py +0 -0
  109. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/custom_slash_commands.py +0 -0
  110. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/effort_menu.py +0 -0
  111. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/effort_ruler.py +0 -0
  112. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/effort_style.py +0 -0
  113. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/env_utils.py +0 -0
  114. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/error_display.py +0 -0
  115. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/exit_confirm_view.py +0 -0
  116. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/exit_watchdog.py +0 -0
  117. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/figures.py +0 -0
  118. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/file_ref_hint.py +0 -0
  119. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/fragment_utils.py +0 -0
  120. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/goal_edit_view.py +0 -0
  121. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/goal_resume_view.py +0 -0
  122. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/history_printer.py +0 -0
  123. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/i18n/__init__.py +0 -0
  124. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/image_chips.py +0 -0
  125. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/input_geometry.py +0 -0
  126. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/jobs_picker.py +0 -0
  127. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/jobs_state.py +0 -0
  128. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/layout_coordinator.py +0 -0
  129. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/locale.py +0 -0
  130. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/logging_adapter.py +0 -0
  131. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/logging_file_handler.py +0 -0
  132. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/logo.py +0 -0
  133. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/markdown_render.py +0 -0
  134. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/mcp_serve.py +0 -0
  135. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/mention_completer.py +0 -0
  136. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/message_style.py +0 -0
  137. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/model_tier_style.py +0 -0
  138. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/models.py +0 -0
  139. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/output_style_menu.py +0 -0
  140. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/__init__.py +0 -0
  141. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/auto_update_runner.py +0 -0
  142. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/auto_update_store.py +0 -0
  143. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/components/__init__.py +0 -0
  144. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/components/detail_view.py +0 -0
  145. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/components/plugin_list.py +0 -0
  146. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/components/search_box.py +0 -0
  147. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/components/tab_bar.py +0 -0
  148. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/marketplace_install_view.py +0 -0
  149. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/operation_state.py +0 -0
  150. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/plugin_picker.py +0 -0
  151. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/tabs/__init__.py +0 -0
  152. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/tabs/discover_tab.py +0 -0
  153. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/tabs/errors_tab.py +0 -0
  154. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/tabs/installed_tab.py +0 -0
  155. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/plugins/tabs/marketplaces_tab.py +0 -0
  156. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/preflight.py +0 -0
  157. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/preflight_wizard.py +0 -0
  158. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/preflight_wizard_ui.py +0 -0
  159. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/print_mode.py +0 -0
  160. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/question_broker.py +0 -0
  161. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/question_view.py +0 -0
  162. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/recap/__init__.py +0 -0
  163. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/recap/controller.py +0 -0
  164. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/resume_picker.py +0 -0
  165. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/resume_preview.py +0 -0
  166. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/resume_selector.py +0 -0
  167. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/rpc_commands.py +0 -0
  168. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/rpc_relay.py +0 -0
  169. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/rpc_stdio.py +0 -0
  170. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/rpc_ws.py +0 -0
  171. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/scm_request_status.py +0 -0
  172. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/selection_menu.py +0 -0
  173. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/side_install.py +0 -0
  174. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/sigint_guard.py +0 -0
  175. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/skill_slash_input.py +0 -0
  176. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/slash_commands.py +0 -0
  177. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/startup.py +0 -0
  178. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/startup_profile.py +0 -0
  179. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/status_bar.py +0 -0
  180. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/statusline/__init__.py +0 -0
  181. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/statusline/model.py +0 -0
  182. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/statusline/picker.py +0 -0
  183. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/statusline/picker_state.py +0 -0
  184. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/statusline/store.py +0 -0
  185. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/stream_pacer.py +0 -0
  186. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/synchronized_output.py +0 -0
  187. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/text_effects.py +0 -0
  188. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/theme.py +0 -0
  189. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_approval_view.py +0 -0
  190. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_fold.py +0 -0
  191. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_fold_view.py +0 -0
  192. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_result_formatters.py +0 -0
  193. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_result_state.py +0 -0
  194. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_result_store.py +0 -0
  195. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_result_viewer.py +0 -0
  196. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tool_view.py +0 -0
  197. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/transcript_viewer.py +0 -0
  198. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui.py +0 -0
  199. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/__init__.py +0 -0
  200. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/approval_queue.py +0 -0
  201. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/btw_view.py +0 -0
  202. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/history_sync.py +0 -0
  203. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/input_behavior.py +0 -0
  204. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/key_bindings.py +0 -0
  205. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/mcp_connecting_view.py +0 -0
  206. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/resize_guard.py +0 -0
  207. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/run_clock.py +0 -0
  208. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/shell_mode.py +0 -0
  209. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/slash_command_registry.py +0 -0
  210. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/tui_parts/ui_mode.py +0 -0
  211. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/ultracode_keyword.py +0 -0
  212. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/update_check.py +0 -0
  213. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/update_messages.py +0 -0
  214. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/workflows_panel.py +0 -0
  215. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_agent/workflows_panel_model.py +0 -0
  216. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/terminal_title.py +0 -0
  217. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/comate_cli/update_cli.py +0 -0
  218. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/docs/cli-rpc-stdio-guide.md +0 -0
  219. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/docs/release-notes/0.12.3.md +0 -0
  220. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/docs/startup-performance.md +0 -0
  221. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/docs/superpowers/plans/2026-07-07-tui-first-repaint-before-sdk-submit.md +0 -0
  222. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/docs/superpowers/plans/2026-07-07-windows-update-manual-rollback.md +0 -0
  223. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/_fake_anthropic_server.py +0 -0
  224. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/_rpc_ws_client.py +0 -0
  225. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/__init__.py +0 -0
  226. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/test_model.py +0 -0
  227. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/test_picker_state.py +0 -0
  228. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/test_picker_ui.py +0 -0
  229. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/test_roundtrip.py +0 -0
  230. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/test_skills_denylist_migration.py +0 -0
  231. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/test_store_load.py +0 -0
  232. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/config/test_store_save.py +0 -0
  233. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/conftest.py +0 -0
  234. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/fixtures/exit_watchdog_child.py +0 -0
  235. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/fixtures/fake_mcp_misbehaving_stdout.py +0 -0
  236. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/recap/test_idle_recap_controller.py +0 -0
  237. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/recap/test_recap_history_rendering.py +0 -0
  238. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/recap/test_tui_idle_recap_integration.py +0 -0
  239. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/statusline/__init__.py +0 -0
  240. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/statusline/test_model.py +0 -0
  241. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/statusline/test_picker_state.py +0 -0
  242. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/statusline/test_store.py +0 -0
  243. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_animations_styles.py +0 -0
  244. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_animator_shuffle.py +0 -0
  245. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_config_check_gate.py +0 -0
  246. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_exit_lifecycle.py +0 -0
  247. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_mcp_preload.py +0 -0
  248. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_mcp_preload_kick.py +0 -0
  249. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_preflight_gate.py +0 -0
  250. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_print_mode.py +0 -0
  251. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_profile_threading.py +0 -0
  252. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_pty_ctrl_b.py +0 -0
  253. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_pty_ctrl_c_exit.py +0 -0
  254. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_pty_shell_mode.py +0 -0
  255. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_pty_smoke.py +0 -0
  256. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_shutdown.py +0 -0
  257. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_startup_latency.py +0 -0
  258. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_startup_order.py +0 -0
  259. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_token_cost_config.py +0 -0
  260. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_app_usage_line.py +0 -0
  261. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_approval_bridge.py +0 -0
  262. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_approval_content_preview.py +0 -0
  263. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_backend_announcements.py +0 -0
  264. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_backend_client.py +0 -0
  265. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_backend_feedback.py +0 -0
  266. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_backend_provider_snapshot.py +0 -0
  267. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_backend_rating.py +0 -0
  268. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_backend_session_report.py +0 -0
  269. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_backend_tasks.py +0 -0
  270. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_btw_slash_command.py +0 -0
  271. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_busy_slash_gating.py +0 -0
  272. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_cli_project_root.py +0 -0
  273. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_clipboard_image_reader.py +0 -0
  274. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_commands_system_messages.py +0 -0
  275. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_compact_command_semantics.py +0 -0
  276. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_completion_context_activation.py +0 -0
  277. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_completion_status_panel.py +0 -0
  278. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_config_check.py +0 -0
  279. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_console_profile.py +0 -0
  280. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_context_command.py +0 -0
  281. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_context_view.py +0 -0
  282. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ctrl_b_background.py +0 -0
  283. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ctrl_c_clear_input.py +0 -0
  284. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_custom_slash_commands.py +0 -0
  285. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_device_identity.py +0 -0
  286. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_discover_tab.py +0 -0
  287. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_distribution_contract.py +0 -0
  288. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_drain_frame_atomicity.py +0 -0
  289. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_effort_menu.py +0 -0
  290. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_effort_menu_frame_rate.py +0 -0
  291. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_effort_ruler.py +0 -0
  292. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_effort_slash_command.py +0 -0
  293. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_effort_style.py +0 -0
  294. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_errors_tab.py +0 -0
  295. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer.py +0 -0
  296. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_approval_wait.py +0 -0
  297. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_boundary.py +0 -0
  298. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_e2e.py +0 -0
  299. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_fixed_overhead.py +0 -0
  300. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_jobs.py +0 -0
  301. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_log_boundary.py +0 -0
  302. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_log_queue.py +0 -0
  303. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_provider_overflow.py +0 -0
  304. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_shell.py +0 -0
  305. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_stream_pacing.py +0 -0
  306. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_stream_staging.py +0 -0
  307. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_streaming.py +0 -0
  308. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_tool_args_progress.py +0 -0
  309. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_event_renderer_tool_fold.py +0 -0
  310. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_exit_confirm_view.py +0 -0
  311. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_exit_guard.py +0 -0
  312. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_exit_watchdog.py +0 -0
  313. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_exit_watchdog_subprocess.py +0 -0
  314. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_file_ref_hint.py +0 -0
  315. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_format_error.py +0 -0
  316. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_goal_edit_handlers.py +0 -0
  317. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_goal_edit_view.py +0 -0
  318. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_goal_paused_hint.py +0 -0
  319. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_goal_resume_tui.py +0 -0
  320. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_goal_resume_view.py +0 -0
  321. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_goal_slash_command.py +0 -0
  322. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_handle_error.py +0 -0
  323. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_drain_throttle.py +0 -0
  324. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_printer.py +0 -0
  325. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_printer_log.py +0 -0
  326. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_printer_styles.py +0 -0
  327. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_printer_subtitle_position.py +0 -0
  328. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_printer_tool_fold.py +0 -0
  329. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_sync.py +0 -0
  330. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_history_sync_tool_fold.py +0 -0
  331. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_i18n.py +0 -0
  332. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_image_chips.py +0 -0
  333. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_image_preprocess_offload_lag.py +0 -0
  334. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_import_weight.py +0 -0
  335. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_input_behavior.py +0 -0
  336. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_input_history.py +0 -0
  337. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_input_separator_counter.py +0 -0
  338. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_installed_tab.py +0 -0
  339. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_interrupt_exit_semantics.py +0 -0
  340. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_jobs_panel.py +0 -0
  341. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_jobs_picker.py +0 -0
  342. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_key_bindings_system_messages.py +0 -0
  343. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_layout_coordinator.py +0 -0
  344. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_loading_modal_suppression.py +0 -0
  345. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_loading_tip_picker.py +0 -0
  346. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_logging_adapter.py +0 -0
  347. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_logging_file_handler.py +0 -0
  348. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_logo.py +0 -0
  349. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_main_args.py +0 -0
  350. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_main_args_yolo.py +0 -0
  351. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_main_profile_entry.py +0 -0
  352. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_markdown_render.py +0 -0
  353. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_marketplaces_tab.py +0 -0
  354. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_mcp_cli.py +0 -0
  355. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_mcp_cli_scope_defaults.py +0 -0
  356. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_mcp_serve.py +0 -0
  357. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_mention_completer.py +0 -0
  358. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_menu_cursor_unification.py +0 -0
  359. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_message_style.py +0 -0
  360. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_modal_freeze_timing.py +0 -0
  361. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_modal_panel_visibility.py +0 -0
  362. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_model_switch_command.py +0 -0
  363. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_model_tier_style.py +0 -0
  364. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_no_raw_colors.py +0 -0
  365. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_output_style_slash_command.py +0 -0
  366. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_permission_mode_cycle.py +0 -0
  367. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_plugin_auto_update_runner.py +0 -0
  368. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_plugin_auto_update_store.py +0 -0
  369. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_plugin_auto_update_tui.py +0 -0
  370. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_plugin_operation_state.py +0 -0
  371. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_plugin_slash_commands.py +0 -0
  372. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_plugin_tui_components.py +0 -0
  373. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_preflight.py +0 -0
  374. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_preflight_copilot.py +0 -0
  375. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_preflight_wizard_ui.py +0 -0
  376. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_pty_output_integrity.py +0 -0
  377. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_question_broker.py +0 -0
  378. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_question_key_bindings.py +0 -0
  379. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_question_view.py +0 -0
  380. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_resize_guard.py +0 -0
  381. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_resume_picker.py +0 -0
  382. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_resume_picker_exit_safety.py +0 -0
  383. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_resume_preview.py +0 -0
  384. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_resume_selector.py +0 -0
  385. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rewind_command_semantics.py +0 -0
  386. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rpc_mode_logging.py +0 -0
  387. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rpc_relay_dial_out.py +0 -0
  388. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rpc_relay_e2e_smoke.py +0 -0
  389. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rpc_relay_process_smoke.py +0 -0
  390. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rpc_v4_stdio_smoke.py +0 -0
  391. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rpc_v4_ws_smoke.py +0 -0
  392. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_rpc_ws_bind_failure.py +0 -0
  393. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_run_clock.py +0 -0
  394. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_running_tool_status_line.py +0 -0
  395. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_scm_request_status.py +0 -0
  396. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_scrollback_write_encoding.py +0 -0
  397. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_selection_menu.py +0 -0
  398. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_session_auto_title.py +0 -0
  399. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_session_query_token_summary.py +0 -0
  400. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_settings_write_guard.py +0 -0
  401. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_shell_mode.py +0 -0
  402. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_shutdown_noise_guard.py +0 -0
  403. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_shutdown_noise_integration.py +0 -0
  404. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_side_install.py +0 -0
  405. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_sigint_guard.py +0 -0
  406. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_sigint_key_binding.py +0 -0
  407. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_skill_slash_input.py +0 -0
  408. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_slash_add_dir.py +0 -0
  409. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_slash_argument_hint.py +0 -0
  410. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_slash_clear.py +0 -0
  411. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_slash_completer.py +0 -0
  412. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_slash_registry.py +0 -0
  413. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_startup_import_budget.py +0 -0
  414. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_startup_profile.py +0 -0
  415. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_status_bar.py +0 -0
  416. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_status_bar_mid_turn_refresh.py +0 -0
  417. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_status_bar_request_status.py +0 -0
  418. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_status_bar_transient.py +0 -0
  419. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_stream_pacer.py +0 -0
  420. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_stream_pacing_tick.py +0 -0
  421. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_stream_staging_panel.py +0 -0
  422. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_style_class_coverage.py +0 -0
  423. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_synchronized_output.py +0 -0
  424. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tab_title.py +0 -0
  425. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_task_panel_format.py +0 -0
  426. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_task_panel_key_bindings.py +0 -0
  427. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_task_poll.py +0 -0
  428. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_terminal_title.py +0 -0
  429. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_theme.py +0 -0
  430. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_todo_panel_busy_gating.py +0 -0
  431. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_approval_key_bindings.py +0 -0
  432. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_approval_tui.py +0 -0
  433. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_approval_view.py +0 -0
  434. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_approval_view_workflow.py +0 -0
  435. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_fold.py +0 -0
  436. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_fold_panel.py +0 -0
  437. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_fold_view.py +0 -0
  438. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_result_formatters.py +0 -0
  439. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_result_state.py +0 -0
  440. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_result_store.py +0 -0
  441. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_result_viewer.py +0 -0
  442. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_result_viewer_key_bindings.py +0 -0
  443. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_view.py +0 -0
  444. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tool_view_styles.py +0 -0
  445. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_transcript_viewer.py +0 -0
  446. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_transcript_viewer_tool_fold.py +0 -0
  447. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_builtin_slash_chain.py +0 -0
  448. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_deferred_prewarm.py +0 -0
  449. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_elapsed_status.py +0 -0
  450. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_esc_queue.py +0 -0
  451. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_exit_idempotence.py +0 -0
  452. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_exit_paced_tail.py +0 -0
  453. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_exit_pending_logs.py +0 -0
  454. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_hot_reload.py +0 -0
  455. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_image_chip_seed.py +0 -0
  456. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_image_paste.py +0 -0
  457. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_image_path_upgrade.py +0 -0
  458. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_image_restore.py +0 -0
  459. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_image_submit.py +0 -0
  460. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_interrupt_queue_recall.py +0 -0
  461. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_llm_retry_panel.py +0 -0
  462. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_loading_tip_rotation.py +0 -0
  463. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_local_interactive_barrier.py +0 -0
  464. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_mcp_init_gate.py +0 -0
  465. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_paste_history_persistence.py +0 -0
  466. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_paste_newline_guard.py +0 -0
  467. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_paste_placeholder.py +0 -0
  468. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_plugin_load.py +0 -0
  469. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_provider_error_shield.py +0 -0
  470. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_queue_pop_images.py +0 -0
  471. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_queue_preview.py +0 -0
  472. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_queue_sdk_source.py +0 -0
  473. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_replace_session_resume_hint.py +0 -0
  474. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_scheduled_fire_log.py +0 -0
  475. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_scratchpad_fold_wiring.py +0 -0
  476. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_send_undo_window.py +0 -0
  477. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_session_observers.py +0 -0
  478. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_shutdown_cancel_propagation.py +0 -0
  479. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_split_invariance.py +0 -0
  480. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_startup_latency.py +0 -0
  481. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_surrogate_repair.py +0 -0
  482. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_thinking_display.py +0 -0
  483. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_tool_result_registry_lifecycle.py +0 -0
  484. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_tui_window_too_small_fallback.py +0 -0
  485. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ui_mode_derivation.py +0 -0
  486. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ui_tick_exception_isolation.py +0 -0
  487. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ultracode_keyword.py +0 -0
  488. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ultracode_keyword_frame_rate.py +0 -0
  489. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ultracode_keyword_submit.py +0 -0
  490. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_ultracode_shimmer_render.py +0 -0
  491. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_update_check.py +0 -0
  492. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_update_cli.py +0 -0
  493. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_upstream_surrogate_merge_characterization.py +0 -0
  494. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_usage_command.py +0 -0
  495. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_wellformed_terminal_input.py +0 -0
  496. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_whitelabel_clear_logo.py +0 -0
  497. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_windows_sigint_console.py +0 -0
  498. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_workflows_panel.py +0 -0
  499. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_workflows_panel_model.py +0 -0
  500. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_wrap_user_text.py +0 -0
  501. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tests/test_zipapp_launcher_path.py +0 -0
  502. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tools/diagnose_windows_shim_rename.py +0 -0
  503. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tools/logo_lab.py +0 -0
  504. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tools/nico_preview.py +0 -0
  505. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tools/probe_conhost_char_width.py +0 -0
  506. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tools/probe_conhost_render_replay.py +0 -0
  507. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tools/startup_bench.py +0 -0
  508. {comate_cli-0.12.4b6 → comate_cli-0.12.4b8}/tools/verify_windows_self_update_semantics.py +0 -0
@@ -4,6 +4,11 @@
4
4
 
5
5
  ### Added
6
6
 
7
+ - 规则双目录(SDK):条件规则(带 `paths:` 的规则文件)现在也从项目 `.claude/rules/` 与用户 `~/.claude/rules/` 读取,Claude Code 里配好的路径规则搬到 comate 下直接生效——Read 命中路径注入 reminder,Edit / Write 预检同样拦截注入;user 层受 user setting source 门控,项目层受 project 门控。同一层级内 `.agent/rules` 与 `.claude/rules` 的同名文件(按相对路径)只加载 `.agent` 那份,被遮蔽路径记 info 日志;用户层与项目层之间不去重,两份都加载。`paths` 支持逗号分隔字符串(`paths: "src/**, lib/**"` 拆成多个模式,剥掉首尾空白与引号),YAML 列表形式不变;rules 目录下指向目录的符号链接跟进(做环检测,同一真实目录只进一次);`.agents/rules/` 不读。目录、去重、逗号、符号链接四项改动作用在统一扫描入口上,常驻规则同样受益。
8
+ - 技能扫描根加入 `.agents`(SDK;含 CLI `/skills` 菜单来源判定修正):`npx skills add` 装进 `.agents/skills/` 的技能直接被发现、可通过 Skill 工具调用,`.claude/skills/` 下指向它的符号链接不会让它列两次;运行中再装一个,下一轮用户输入后热发现也能看到。扫描根顺序即优先级,同名先到先得:项目 `.agent/skills` → `.agents/skills` → `.claude/skills`;用户 `~/.agent/skills` → `~/.agents/skills` → `~/.config/agents/skills` → `~/.claude/skills`,两层各受对应 setting source 门控。四类扫描根下以 `.` 开头的子目录一律跳过(不当作 skill 也不当作 namespace)。`/skills` 菜单的同名去重与来源判定改按真实路径(扫描根与 skill 目录两边 resolve 后再比),符号链接 skill 归入正确分组、不再兜底成 user,project 组副标题自动列出 `.agents/skills`。
9
+ - MCP 工具停用(SDK 部分,菜单在后续版本):`.mcp.json` 的 server 条目新增可选字段 `disabled_tools`(字符串数组,写 server 自报的原始工具名,精确匹配、不支持通配符),列出的工具不再发给模型、子 agent 点名也拿不到;没列出的工具与 server 新增的工具照常加载,名单里写了 server 不提供的名字不报错。代码里传的 `mcp_servers`(含 `type: "sdk"`)认同一个字段。新增存盘函数 `comate_agent_sdk.mcp.set_mcp_server_disabled_tools(alias, names, *, scope, project_root)`:只改该条目的这一个字段,空名单即删除字段,对 `{"enabled": false}` 墓碑条目报错。新增 `AgentRuntime.set_mcp_disabled_tools(alias, names)`:会话中途改名单,不重连任何 server,下一次模型请求生效(实测 3 台 × 50 个工具单次约 2.4ms)。一台 server 的工具全部停用时它保持连接,但它的 instructions 不再发给模型。旧版本 SDK 会忽略这个字段并加载全部工具。
10
+ - `/mcp` 工具列表可按工具启用 / 停用:每行前显示 `[x]`(启用)/ `[ ]`(停用),停用的工具仍留在列表里;Space 切换当前行并立刻写回该 server 所在层的 `.mcp.json`(`disabled_tools` 字段),不重连任何 server,下一次模型请求生效,agent 忙碌时也可切换;Enter 仍进工具详情,详情页多一行启用 / 停用状态。存盘失败时勾选不变,菜单里显示一行错误。server 详情页有停用时显示 `Tools: 5 / 40 tools`,整台 Enable 后的「tools loaded」只数启用的工具;一台 server 的工具全部停用后 `View tools` 入口仍在,可以进去重新启用。新文案三语齐全。comate-cli 的 `comate-agent-sdk` 下限抬到 0.12.15(SDK 同步升版)。
11
+ - 空闲修剪提示与开关:SDK 使用方升级后默认启用空闲修剪(会话空闲超 3 小时后,新一轮发出前把较早的 Read / Bash 等可重取工具结果换成占位符,少付缓存已凉后的全价重读),可用 `AgentConfig(idle_pruning=False)` 关闭;CLI 用户可在 settings.json 顶层写 `"idle_pruning": false` 关闭(不写 = 开,三层合并)。修剪真的发生时终端显示一行「已清理 N 条较早的工具结果,约省 X tokens(空闲 H 小时)」,模型随后重读文件不再是莫名其妙的动作;resume 后已清理条目保持占位符,不重复修剪、不重复提示。
7
12
  - `--system-prompt <文本>` / `--system-prompt-file <路径>`:用自己的文字替换 system prompt 的开头段(agent 是谁、怎么干活);`--append-system-prompt <文本>` / `--append-system-prompt-file <路径>`:在护栏之后追加。参数名对齐 Claude Code,但与 Claude Code 不同的是护栏段(运行环境说明、工作纪律、危险操作确认、汇报规范等)始终保留。替换与追加可同时使用;同类的文本版与文件版同时给、值为空、文件读不了或为空都会当场退出并按界面语言提示。`--rpc-*` 与 `-p` 同样生效,一个进程下所有新会话共用;resume 旧会话时沿用会话创建时的 system prompt,界面会给出提示,`/clear` 后生效。白牌 `system_role` 语义不变:只换品牌身份句,编码规则保留。
8
13
  - ctrl+b 把正在前台跑的 shell 命令转到后台:对模型调用的 Bash 工具和 `!` 本地命令都生效。同一个进程原样移交给后台 job(不重启不杀),模型 Bash 的工具结果立刻回「用户已转后台 + job_id + 输出尾部」让模型继续本轮;`!` 命令静默记一条 reminder、解锁输入框。后台跑完走既有 job 完成通知叫模型;想停用 `/ps`。运行面板与 `!` 活动区在 Bash 跑时显示「ctrl+b 转后台」提示,`/help` 多一行说明。没有可转后台的命令时按键只闪一条提示;子 agent 里的 Bash 不受影响。tmux 用户需按两次 ctrl+b。
9
14
  - `!` shell 模式:空输入框敲 `!` 进入 shell 模式,回车后命令在本地直接执行(跳过权限审批、与模型共享持久 cwd),滚动区显示 `! cmd` + 紧贴其下的 `⎿` 输出块(stderr 红、stdout 不红、空输出标 `(No output)`、控制码剥净、长输出截断可 Ctrl+O 看全文)。命令结束后模型自动简短回应一轮;运行期间敲的提问并入同一轮。运行中锚点下方实时显示最后 5 行输出与耗时;超过 60 秒自动转后台并解锁输入框,后台跑完再叫模型;Esc/Ctrl+C 中断不叫模型并把命令回填到输入框。忙时 `!cmd` 排队,回合结束后按顺序执行。
@@ -59,6 +64,7 @@
59
64
 
60
65
  ### Changed
61
66
 
67
+ - 常驻规则进置顶区(SDK):规则目录(`~/.agent/rules`、`~/.claude/rules`、项目 `.agent/rules`、`.claude/rules`)里没有有效 `paths:` 的文件——没有 frontmatter、frontmatter YAML 写坏、`paths` 只写了 `**` 之类全匹配——不再被丢弃,而是像 Claude Code 一样启动就加载,和 AGENTS.md 一起常驻。顺序:用户 AGENTS.md → 用户层常驻规则 → 项目 AGENTS.md 链 → 项目层常驻规则(同层 `.agent` 先、`.claude` 后)。进模型的是剥掉 frontmatter 和 HTML 注释后的正文;置顶区文件清单带上每条规则的路径与 token 数;compact、`/clear`、resume 后仍在。user 层受 user setting source 门控,项目层受 project 门控;计入置顶区既有的 token 告警阈值,不截断。**行为变更**:`.agent/rules` 下以前被静默丢弃的无 `paths` 文件从本版起生效。
62
68
  - 首启向导(Provider setup)整体重做,照 `/effort` 刻度尺模式改为自绘组件 `preflight_wizard_ui.WizardScreenUI`,不再借用共用的 `SelectionMenuUI`:六屏统一「标题 / 空行 / 内容 / 空行 / 键位提示」顶部对齐骨架;选项行改为 `❯ label` 无圆点、项间不留空行;provider 屏只在选中项下方显示一行 preset 说明;API key / endpoint / 模型名输入屏去掉边框;确认屏的 JSON 预览改为对齐缩进的静态块;键位提示只写真正绑定的键(去掉并不存在的 k/j)。其它菜单不受影响。
63
69
  - `/effort` 的 `ultracode` 改绑 `max` 档(原 `xhigh`):选 ultracode = 最高思考档 + workflows
64
70
  多 agent 编排;`/effort max` 或 `auto` 关开关,`xhigh` 变回普通档。刻度尺描述改为
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comate-cli
3
- Version: 0.12.4b6
3
+ Version: 0.12.4b8
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.13
18
+ Requires-Dist: comate-agent-sdk<0.13,>=0.12.15
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
@@ -15,6 +15,7 @@ from comate_agent_sdk.agent.events import (
15
15
  CompactionResultEvent,
16
16
  CompactionStartedEvent,
17
17
  FixedOverheadDetail,
18
+ IdlePruneEvent,
18
19
  JobCompletedEvent,
19
20
  JobProgressEvent,
20
21
  JobStartedEvent,
@@ -2374,6 +2375,21 @@ class EventRenderer:
2374
2375
  self._append_history_entry(
2375
2376
  HistoryEntry(entry_type="thinking", text=thinking)
2376
2377
  )
2378
+ case IdlePruneEvent(
2379
+ item_count=item_count,
2380
+ tokens_saved=tokens_saved,
2381
+ idle_seconds=idle_seconds,
2382
+ ):
2383
+ # 空闲修剪:模型接下来会重读文件,先给用户一行解释(票 03)
2384
+ self.append_system_message(
2385
+ i18n(
2386
+ i18n_message.idle_prune_notice,
2387
+ item_count=item_count,
2388
+ tokens_saved=f"{tokens_saved:,}",
2389
+ idle_hours=f"{idle_seconds / 3600:.1f}",
2390
+ ),
2391
+ severity="info",
2392
+ )
2377
2393
  case CompactionStartedEvent(
2378
2394
  current_tokens=_,
2379
2395
  threshold=_,
@@ -122,6 +122,10 @@ EN: dict[str, str] = {
122
122
  "goal_paused_hint": (
123
123
  "Goal paused. Use /goal resume to continue, or /goal clear to drop it."
124
124
  ),
125
+ "idle_prune_notice": (
126
+ "Pruned {item_count} older tool results, saving ~{tokens_saved} tokens "
127
+ "(idle for {idle_hours} h)"
128
+ ),
125
129
  "image_clipboard_empty": "No image in the clipboard.",
126
130
  "image_clipboard_reader_missing": (
127
131
  "No clipboard reader command found (xclip or wl-paste). "
@@ -159,6 +163,14 @@ EN: dict[str, str] = {
159
163
  "Interrupt signal sent. Press Esc again to force interrupt, "
160
164
  "or Ctrl+C again to exit."
161
165
  ),
166
+ "mcp_server_tools_enabled_of_total": "Tools: {enabled_count} / {total_count} tools",
167
+ "mcp_tool_status_disabled": "Status: disabled",
168
+ "mcp_tool_status_enabled": "Status: enabled",
169
+ "mcp_tool_toggle_apply_failed": "The setting is saved, but this session did not apply it: {error}",
170
+ "mcp_tool_toggle_save_failed": "Could not save the tool setting: {error}",
171
+ "mcp_tools_count_enabled_of_total": "{enabled_count} / {total_count} tools",
172
+ "mcp_tools_key_hints": "or k/j: Move Space: Turn on/off Enter: Details Esc: Back",
173
+ "mcp_tools_read_only": "The config of this server is not in a .mcp.json file. You cannot change its tools here.",
162
174
  "mode_switch_failed": "Failed to switch permission mode: {error}",
163
175
  "output_style_cancelled": "Output style change cancelled.",
164
176
  "output_style_global_requires_name": "--global needs a style name, e.g. /output-style learning --global",
@@ -128,6 +128,10 @@ JA: dict[str, str] = {
128
128
  "goal_paused_hint": (
129
129
  "ゴールは一時停止されました。/goal resume で再開、/goal clear で破棄できます。"
130
130
  ),
131
+ "idle_prune_notice": (
132
+ "古いツール結果を {item_count} 件整理し、約 {tokens_saved} トークン節約しました"
133
+ "({idle_hours} 時間アイドル後)"
134
+ ),
131
135
  "image_clipboard_empty": "クリップボードに画像がありません。",
132
136
  "image_clipboard_reader_missing": (
133
137
  "クリップボード読み取りコマンド(xclip または wl-paste)が見つかりません。"
@@ -166,6 +170,14 @@ JA: dict[str, str] = {
166
170
  "中断シグナルを送信しました。もう一度 Esc を押すと強制中断し、"
167
171
  "もう一度 Ctrl+C を押すと終了します。"
168
172
  ),
173
+ "mcp_server_tools_enabled_of_total": "ツール:{enabled_count} / {total_count} 個",
174
+ "mcp_tool_status_disabled": "状態:無効",
175
+ "mcp_tool_status_enabled": "状態:有効",
176
+ "mcp_tool_toggle_apply_failed": "保存しましたが、現在のセッションに反映できませんでした:{error}",
177
+ "mcp_tool_toggle_save_failed": "ツールの設定を保存できませんでした:{error}",
178
+ "mcp_tools_count_enabled_of_total": "{enabled_count} / {total_count} 個のツール",
179
+ "mcp_tools_key_hints": "または k/j:移動 Space:有効/無効 Enter:詳細 Esc:戻る",
180
+ "mcp_tools_read_only": "このサーバーの設定は .mcp.json ファイルにないため、ここではツールを変更できません。",
169
181
  "mode_switch_failed": "権限モードの切り替えに失敗しました:{error}",
170
182
  "output_style_cancelled": "出力スタイルの変更をキャンセルしました。",
171
183
  "output_style_global_requires_name": "--global にはスタイル名が必要です。例:/output-style learning --global",
@@ -92,6 +92,9 @@ ZH: dict[str, str] = {
92
92
  "feedback_value_unknown": "未知",
93
93
  "file_log_write_failed": "日志文件写入异常,本次会话的文件日志可能不完整(不影响正常使用)。",
94
94
  "goal_paused_hint": "Goal 已暂停。使用 /goal resume 继续,或 /goal clear 清除。",
95
+ "idle_prune_notice": (
96
+ "已清理 {item_count} 条较早的工具结果,约省 {tokens_saved} tokens(空闲 {idle_hours} 小时)"
97
+ ),
95
98
  "image_clipboard_empty": "剪贴板中没有图片。",
96
99
  "image_clipboard_reader_missing": (
97
100
  "未找到剪贴板读取命令(xclip 或 wl-paste),"
@@ -112,6 +115,14 @@ ZH: dict[str, str] = {
112
115
  "interrupt_force_or_exit_hint": (
113
116
  "已发送中断信号。再次按 Esc 可强制中断,再次按 Ctrl+C 可退出。"
114
117
  ),
118
+ "mcp_server_tools_enabled_of_total": "工具:{enabled_count} / {total_count} 个",
119
+ "mcp_tool_status_disabled": "状态:已停用",
120
+ "mcp_tool_status_enabled": "状态:已启用",
121
+ "mcp_tool_toggle_apply_failed": "已存盘,但没能在当前会话生效:{error}",
122
+ "mcp_tool_toggle_save_failed": "工具开关没能存盘:{error}",
123
+ "mcp_tools_count_enabled_of_total": "{enabled_count} / {total_count} 个工具",
124
+ "mcp_tools_key_hints": "或 k/j:移动 Space:启用/停用 Enter:详情 Esc:返回",
125
+ "mcp_tools_read_only": "此 server 的配置不在 .mcp.json 文件里,不能在这里修改工具开关。",
115
126
  "mode_switch_failed": "切换权限模式失败:{error}",
116
127
  "output_style_cancelled": "已取消切换输出风格。",
117
128
  "output_style_global_requires_name": "--global 需要带上风格名,例如:/output-style learning --global",
@@ -87,6 +87,7 @@ class message(StrEnum): # noqa: N801 - 调用形态是 i18n(message.key),小
87
87
  feedback_value_unknown = "feedback_value_unknown"
88
88
  file_log_write_failed = "file_log_write_failed"
89
89
  goal_paused_hint = "goal_paused_hint"
90
+ idle_prune_notice = "idle_prune_notice"
90
91
  image_clipboard_empty = "image_clipboard_empty"
91
92
  image_clipboard_reader_missing = "image_clipboard_reader_missing"
92
93
  image_dropped_feedback_draft = "image_dropped_feedback_draft"
@@ -101,6 +102,14 @@ class message(StrEnum): # noqa: N801 - 调用形态是 i18n(message.key),小
101
102
  input_cleared_recall_hint = "input_cleared_recall_hint"
102
103
  input_cleared_recall_interrupt_hint = "input_cleared_recall_interrupt_hint"
103
104
  interrupt_force_or_exit_hint = "interrupt_force_or_exit_hint"
105
+ mcp_server_tools_enabled_of_total = "mcp_server_tools_enabled_of_total"
106
+ mcp_tool_status_disabled = "mcp_tool_status_disabled"
107
+ mcp_tool_status_enabled = "mcp_tool_status_enabled"
108
+ mcp_tool_toggle_apply_failed = "mcp_tool_toggle_apply_failed"
109
+ mcp_tool_toggle_save_failed = "mcp_tool_toggle_save_failed"
110
+ mcp_tools_count_enabled_of_total = "mcp_tools_count_enabled_of_total"
111
+ mcp_tools_key_hints = "mcp_tools_key_hints"
112
+ mcp_tools_read_only = "mcp_tools_read_only"
104
113
  mode_switch_failed = "mode_switch_failed"
105
114
  output_style_cancelled = "output_style_cancelled"
106
115
  output_style_global_requires_name = "output_style_global_requires_name"
@@ -76,6 +76,18 @@ def _is_within(path: Path, root: Path) -> bool:
76
76
  return path == root or root in path.parents
77
77
 
78
78
 
79
+ def _resolved_roots(roots: Sequence[Path]) -> list[Path]:
80
+ return [resolved for resolved in (_normalized(root) for root in roots) if resolved is not None]
81
+
82
+
83
+ def _layer_of(path: Path, project_roots: Sequence[Path], user_roots: Sequence[Path]) -> str | None:
84
+ if any(_is_within(path, root) for root in project_roots):
85
+ return "project"
86
+ if any(_is_within(path, root) for root in user_roots):
87
+ return "user"
88
+ return None
89
+
90
+
79
91
  def _resolve_source(
80
92
  skill: Any,
81
93
  *,
@@ -100,22 +112,26 @@ def _resolve_source(
100
112
  bundled_root = _normalized(bundled_skills_dir())
101
113
  if bundled_root is not None and _is_within(resolved, bundled_root):
102
114
  return "builtin"
103
- if any(_is_within(resolved, root) for root in project_roots):
104
- return "project"
105
- if any(_is_within(resolved, root) for root in user_roots):
106
- return "user"
115
+ # 先按真实路径比(扫描根也 resolve,扫描根本身是符号链接时才对得上);
116
+ # skill 链到所有扫描根之外时真实路径落空,再按扫描时的原路径比,不兜底成 user。
117
+ layer = _layer_of(
118
+ resolved, _resolved_roots(project_roots), _resolved_roots(user_roots)
119
+ ) or _layer_of(base_dir.expanduser(), project_roots, user_roots)
120
+ if layer is not None:
121
+ return layer
107
122
  return "user"
108
123
 
109
124
 
110
125
  def _split_scan_roots(
111
126
  project_root: Path | str | None,
112
127
  ) -> tuple[list[Path], list[Path]]:
113
- """扫描根拆成项目层与用户层;按「是否挂在 home 下」判断,不依赖 SDK 的返回顺序。"""
114
- scan_roots = skill_scan_roots(project_root if project_root is not None else Path.cwd())
115
- home = _normalized(Path.home())
116
- user_roots = [root for root in scan_roots if home is not None and root.parent.parent == home]
117
- project_roots = [root for root in scan_roots if root not in user_roots]
118
- return project_roots, user_roots
128
+ """扫描根拆成项目层与用户层;按 SDK 的配置层过滤取,不按目录形状猜
129
+ (`~/.config/agents/skills` 不直接挂在 home 下)。"""
130
+ root = project_root if project_root is not None else Path.cwd()
131
+ return (
132
+ skill_scan_roots(root, sources=("project",)),
133
+ skill_scan_roots(root, sources=("user",)),
134
+ )
119
135
 
120
136
 
121
137
  def build_skill_menu_rows(
@@ -227,9 +227,14 @@ LOADING_TIP_PAIRS: tuple[LoadingTip, ...] = (
227
227
  ja="自作コマンドは shell 出力やファイル内容を埋め込めます",
228
228
  ),
229
229
  LoadingTip(
230
- en="Rules in .agent/rules/ load only when matching files appear.",
231
- zh=".agent/rules/ 的规则只在碰到指定路径的文件时才注入",
232
- ja=".agent/rules/ の規則は該当ファイル出現時のみ注入",
230
+ en=".agent and .claude rules load at startup, or on paths: match.",
231
+ zh=".agent 与 .claude 规则都读;带 paths: 命中才注入,不带启动加载",
232
+ ja=".agent と .claude の両方を読む。paths: は一致時、なしは起動時",
233
+ ),
234
+ LoadingTip(
235
+ en="Use npx skills add; skills in .agents/skills/ work as-is.",
236
+ zh="npx skills add 装进 .agents/skills/ 的技能直接用,不用挪目录",
237
+ ja="npx skills add で .agents/skills/ に追加、そのまま使えます",
233
238
  ),
234
239
  LoadingTip(
235
240
  en="Define your own subagents as .md files under .agent/agents.",
@@ -67,6 +67,10 @@ if TYPE_CHECKING:
67
67
  _GLOBAL_FLAG_RE = re.compile(r"(?:(?<=\s)|^)(?:--global|-g)(?=\s|$)")
68
68
 
69
69
 
70
+ # `/mcp` 菜单能改写的配置层:只有这三层落在磁盘 .mcp.json 上。
71
+ _MCP_WRITABLE_SCOPES = frozenset({"user", "project", "local"})
72
+
73
+
70
74
  def _strip_global_flag(args: str) -> tuple[str, bool]:
71
75
  """从参数串里摘出 `--global` / `-g`,返回 (剩余参数, 是否出现)。剩余部分只去首尾空白。"""
72
76
  stripped, count = _GLOBAL_FLAG_RE.subn("", args)
@@ -78,6 +82,8 @@ class CommandsMixin:
78
82
  _skills_menu_rows: dict[str, SkillMenuRow] = {}
79
83
  # `/skills` 菜单会话内发生过启停:关闭菜单时一次性补发 listing delta。
80
84
  _skills_listing_flush_pending: bool = False
85
+ # `/mcp` 工具列表当前打开的 server;离开工具列表时清空,异步刷新据此判断还能不能改菜单。
86
+ _mcp_tools_menu_alias: str | None = None
81
87
 
82
88
  def _sync_local_interactive_ui_barrier(self) -> None:
83
89
  return
@@ -950,9 +956,12 @@ class CommandsMixin:
950
956
  info_rows = list(getattr(manager, "tool_infos", []) or []) if manager is not None else []
951
957
  failed_rows = list(getattr(manager, "failed_servers", []) or []) if manager is not None else []
952
958
  state_rows = dict(getattr(manager, "server_states", {}) or {}) if manager is not None else {}
959
+ disabled_names_fn = getattr(manager, "disabled_tool_names", None)
953
960
 
954
- tools_by_alias: dict[str, list[dict[str, str]]] = {}
961
+ # 账本 tool_infos 是全集(含停用的);停用与否以 manager 为准,不回头读配置比对。
962
+ tools_by_alias: dict[str, list[dict[str, Any]]] = {}
955
963
  tool_count_by_alias: dict[str, int] = {}
964
+ enabled_count_by_alias: dict[str, int] = {}
956
965
  for info in info_rows:
957
966
  alias = str(getattr(info, "server_alias", "")).strip()
958
967
  if not alias:
@@ -960,14 +969,18 @@ class CommandsMixin:
960
969
  remote_name = str(getattr(info, "remote_name", "")).strip()
961
970
  mapped_name = str(getattr(info, "mapped_name", "")).strip()
962
971
  description = str(getattr(info, "description", "")).strip()
972
+ disabled = callable(disabled_names_fn) and remote_name in disabled_names_fn(alias)
963
973
  tools_by_alias.setdefault(alias, []).append(
964
974
  {
965
975
  "remote_name": remote_name or mapped_name or "(unknown tool)",
966
976
  "mapped_name": mapped_name or remote_name or "(unknown tool)",
967
977
  "description": description or "(No description)",
978
+ "disabled": disabled,
968
979
  }
969
980
  )
970
981
  tool_count_by_alias[alias] = tool_count_by_alias.get(alias, 0) + 1
982
+ if not disabled:
983
+ enabled_count_by_alias[alias] = enabled_count_by_alias.get(alias, 0) + 1
971
984
 
972
985
  failed_reason_by_alias: dict[str, str] = {
973
986
  str(alias): str(reason) for alias, reason in failed_rows
@@ -979,15 +992,15 @@ class CommandsMixin:
979
992
  server_type = str(cfg.get("type", "stdio")).strip().upper() # type: ignore[attr-defined]
980
993
  endpoint = self._format_mcp_endpoint(cfg)
981
994
  enabled = bool(cfg.get("enabled", True)) # type: ignore[attr-defined]
995
+ # 总数与启用数都只从账本算(票 01:state.tool_count 是连接那一刻的自报数,
996
+ # TTL 刷新后会和账本对不上)。
982
997
  tool_count = 0 if not enabled else int(tool_count_by_alias.get(alias, 0))
998
+ enabled_tool_count = 0 if not enabled else int(enabled_count_by_alias.get(alias, 0))
983
999
  tools = [] if not enabled else list(tools_by_alias.get(alias, []))
984
1000
  tools.sort(key=lambda item: item["remote_name"].lower())
985
1001
  state = state_rows.get(alias)
986
1002
  raw_status = str(getattr(state, "status", "") or "").strip().lower()
987
1003
  state_reason = str(getattr(state, "reason", "") or "").strip() or None
988
- state_tool_count = int(getattr(state, "tool_count", tool_count) or 0)
989
- if enabled and raw_status == "connected":
990
- tool_count = state_tool_count
991
1004
 
992
1005
  if not enabled:
993
1006
  status = f"{EFFORT_LOW} Disabled"
@@ -1003,6 +1016,7 @@ class CommandsMixin:
1003
1016
  elif raw_status == "failed":
1004
1017
  status = f"{CROSS_MARK} {state_reason}" if state_reason else f"{CROSS_MARK} Not connected"
1005
1018
  tool_count = 0
1019
+ enabled_tool_count = 0
1006
1020
  elif raw_status == "connected":
1007
1021
  status = f"{CHECK_MARK} Connected"
1008
1022
  elif tool_count > 0:
@@ -1033,6 +1047,7 @@ class CommandsMixin:
1033
1047
  "status": status,
1034
1048
  "raw_status": raw_status,
1035
1049
  "tool_count": tool_count,
1050
+ "enabled_tool_count": enabled_tool_count,
1036
1051
  "tools": tools,
1037
1052
  "config_location": config_location,
1038
1053
  "config_scope": config_scope,
@@ -1202,15 +1217,18 @@ class CommandsMixin:
1202
1217
  return
1203
1218
 
1204
1219
  tool_count = int(row["tool_count"])
1220
+ enabled_tool_count = int(row.get("enabled_tool_count", tool_count))
1221
+ has_disabled_tools = enabled_tool_count < tool_count
1205
1222
  options: list[dict[str, str]] = []
1206
1223
  raw_status = str(row.get("raw_status", "")).strip().lower()
1207
1224
  is_disabled = raw_status == "disabled" or not bool(row.get("enabled", True))
1225
+ # tool_count 是账本全集:工具全部停用后入口仍在,用户才能回来重新启用。
1208
1226
  if raw_status == "connected" and tool_count > 0:
1209
1227
  options.append(
1210
1228
  {
1211
1229
  "value": "view_tools",
1212
1230
  "label": "View tools",
1213
- "description": f"{tool_count} tools",
1231
+ "description": self._mcp_tools_count_text(enabled_tool_count, tool_count),
1214
1232
  }
1215
1233
  )
1216
1234
  if not is_disabled and raw_status != "connecting":
@@ -1244,7 +1262,15 @@ class CommandsMixin:
1244
1262
  f"Status: {row['status']}",
1245
1263
  f"Config location: {row['config_location']}",
1246
1264
  "Capabilities: tools",
1247
- f"Tools: {tool_count} tools",
1265
+ (
1266
+ i18n(
1267
+ message.mcp_server_tools_enabled_of_total,
1268
+ enabled_count=enabled_tool_count,
1269
+ total_count=tool_count,
1270
+ )
1271
+ if has_disabled_tools
1272
+ else f"Tools: {tool_count} tools"
1273
+ ),
1248
1274
  ]
1249
1275
 
1250
1276
  def on_confirm(value: str) -> None:
@@ -1348,9 +1374,15 @@ class CommandsMixin:
1348
1374
  mgr = getattr(agent_runtime, "_mcp_manager", None)
1349
1375
  tool_count = 0
1350
1376
  if mgr:
1377
+ # 只数启用的工具:停用的不发给模型,不算「loaded」。
1378
+ disabled_names_fn = getattr(mgr, "disabled_tool_names", None)
1379
+ disabled_names = (
1380
+ disabled_names_fn(alias) if callable(disabled_names_fn) else frozenset()
1381
+ )
1351
1382
  tool_count = sum(
1352
1383
  1 for info in (getattr(mgr, "tool_infos", None) or [])
1353
1384
  if getattr(info, "server_alias", "") == alias
1385
+ and getattr(info, "remote_name", "") not in disabled_names
1354
1386
  )
1355
1387
  message = f"{past_action} {alias}. ({tool_count} tools loaded)"
1356
1388
  else:
@@ -1481,25 +1513,17 @@ class CommandsMixin:
1481
1513
  )
1482
1514
  self._refresh_layers()
1483
1515
  return
1484
- tools = list(row["tools"])
1485
- options: list[dict[str, str]] = []
1486
- for index, tool in enumerate(tools, start=1):
1487
- options.append(
1488
- {
1489
- "value": str(tool["mapped_name"]),
1490
- "label": f"{index}. {tool['remote_name']}",
1491
- "description": str(tool["mapped_name"]),
1492
- }
1516
+ read_only = str(row.get("config_scope", "")).strip().lower() not in _MCP_WRITABLE_SCOPES
1517
+
1518
+ def on_toggle(value: str) -> None:
1519
+ self._toggle_mcp_tool_disabled(
1520
+ rows_by_alias=rows_by_alias,
1521
+ alias=alias,
1522
+ mapped_name=str(value).strip(),
1493
1523
  )
1494
- options.append(
1495
- {
1496
- "value": "back",
1497
- "label": "Back",
1498
- "description": f"Return to {alias}",
1499
- }
1500
- )
1501
1524
 
1502
1525
  def on_confirm(value: str) -> None:
1526
+ self._mcp_tools_menu_alias = None
1503
1527
  selected = str(value).strip()
1504
1528
  if selected == "back":
1505
1529
  self._mark_local_ui_transition_pending()
@@ -1520,6 +1544,7 @@ class CommandsMixin:
1520
1544
  )
1521
1545
 
1522
1546
  def on_cancel() -> None:
1547
+ self._mcp_tools_menu_alias = None
1523
1548
  self._mark_local_ui_transition_pending()
1524
1549
  self._schedule_background(
1525
1550
  self._open_mcp_server_detail_menu_async(
@@ -1528,12 +1553,15 @@ class CommandsMixin:
1528
1553
  )
1529
1554
  )
1530
1555
 
1556
+ # 只读 server 不注册 on_toggle:Space 绑定的 filter 为假,按键直接失效。
1531
1557
  ok = self._selection_ui.set_options(
1532
1558
  title=f"Tools for {alias}",
1533
- options=options,
1559
+ options=self._mcp_tools_menu_options(row),
1534
1560
  on_confirm=on_confirm,
1535
1561
  on_cancel=on_cancel,
1536
- context_lines=[f"{len(tools)} tools"],
1562
+ on_toggle=None if read_only else on_toggle,
1563
+ key_hints=None if read_only else i18n(message.mcp_tools_key_hints),
1564
+ context_lines=self._mcp_tools_context_lines(row),
1537
1565
  )
1538
1566
  if not ok:
1539
1567
  self._append_slash_command_result(
@@ -1542,11 +1570,157 @@ class CommandsMixin:
1542
1570
  )
1543
1571
  self._refresh_layers()
1544
1572
  return
1573
+ self._mcp_tools_menu_alias = alias
1545
1574
  self._selection_ui.refresh()
1546
1575
  self._set_ui_mode(UIMode.SELECTION)
1547
1576
  self._sync_focus_for_mode()
1548
1577
  self._invalidate()
1549
1578
 
1579
+ @staticmethod
1580
+ def _mcp_tools_menu_options(row: dict[str, Any]) -> list[dict[str, str]]:
1581
+ alias = str(row["alias"])
1582
+ options: list[dict[str, str]] = []
1583
+ for index, tool in enumerate(row["tools"], start=1):
1584
+ mark = "[ ]" if tool.get("disabled") else "[x]"
1585
+ options.append(
1586
+ {
1587
+ "value": str(tool["mapped_name"]),
1588
+ "label": f"{mark} {index}. {tool['remote_name']}",
1589
+ "description": str(tool["mapped_name"]),
1590
+ }
1591
+ )
1592
+ options.append(
1593
+ {
1594
+ "value": "back",
1595
+ "label": "Back",
1596
+ "description": f"Return to {alias}",
1597
+ }
1598
+ )
1599
+ return options
1600
+
1601
+ @staticmethod
1602
+ def _mcp_tools_count_text(enabled_tool_count: int, tool_count: int) -> str:
1603
+ if enabled_tool_count < tool_count:
1604
+ return i18n(
1605
+ message.mcp_tools_count_enabled_of_total,
1606
+ enabled_count=enabled_tool_count,
1607
+ total_count=tool_count,
1608
+ )
1609
+ return f"{tool_count} tools"
1610
+
1611
+ @staticmethod
1612
+ def _mcp_tools_context_lines(row: dict[str, Any], *, error: str | None = None) -> list[str]:
1613
+ enabled_tool_count = sum(1 for tool in row["tools"] if not tool.get("disabled"))
1614
+ lines = [CommandsMixin._mcp_tools_count_text(enabled_tool_count, len(row["tools"]))]
1615
+ if str(row.get("config_scope", "")).strip().lower() not in _MCP_WRITABLE_SCOPES:
1616
+ lines.append(i18n(message.mcp_tools_read_only))
1617
+ if error:
1618
+ lines.append(error)
1619
+ return lines
1620
+
1621
+ def _toggle_mcp_tool_disabled(
1622
+ self,
1623
+ *,
1624
+ rows_by_alias: dict[str, dict[str, Any]],
1625
+ alias: str,
1626
+ mapped_name: str,
1627
+ ) -> None:
1628
+ """`/mcp` 工具列表里按 Space 停用 / 启用一个工具(ADR-0032)。
1629
+
1630
+ 顺序即契约:先写该 server 所在层的 .mcp.json,成功后才改运行时名单,
1631
+ 最后原地刷新勾选。写盘失败则运行时与勾选都不变,菜单里显示一行错误。
1632
+ 不走整台开关那条 invalidate + 强制重载的路:那会重连全部 server。
1633
+ """
1634
+ row = rows_by_alias.get(alias)
1635
+ if row is None:
1636
+ return
1637
+ tool = next(
1638
+ (item for item in row["tools"] if str(item["mapped_name"]) == mapped_name),
1639
+ None,
1640
+ )
1641
+ if tool is None:
1642
+ # Back 行。
1643
+ return
1644
+ config_scope = str(row.get("config_scope", "")).strip().lower()
1645
+ if config_scope not in _MCP_WRITABLE_SCOPES:
1646
+ return
1647
+
1648
+ remote_name = str(tool["remote_name"])
1649
+ project_root = getattr(self._session, "_cwd", None)
1650
+ try:
1651
+ from comate_agent_sdk.mcp import load_scope_servers, set_mcp_server_disabled_tools
1652
+
1653
+ servers = load_scope_servers(
1654
+ scope=config_scope, # type: ignore[arg-type]
1655
+ project_root=project_root,
1656
+ include_disabled=True,
1657
+ )
1658
+ # 以磁盘条目现有名单为底,只增删这一个名字:server 不提供的名字原样保留(Q11)。
1659
+ current = [str(name) for name in (servers.get(alias, {}).get("disabled_tools") or [])]
1660
+ if tool.get("disabled"):
1661
+ names = [name for name in current if name != remote_name]
1662
+ elif remote_name in current:
1663
+ names = current
1664
+ else:
1665
+ names = [*current, remote_name]
1666
+ set_mcp_server_disabled_tools(
1667
+ alias,
1668
+ names,
1669
+ scope=config_scope, # type: ignore[arg-type]
1670
+ project_root=project_root,
1671
+ )
1672
+ except Exception as exc:
1673
+ logger.warning("Failed to save disabled MCP tools for '%s': %s", alias, exc)
1674
+ self._selection_ui.update_context_lines(
1675
+ self._mcp_tools_context_lines(
1676
+ row,
1677
+ error=i18n(message.mcp_tool_toggle_save_failed, error=exc),
1678
+ )
1679
+ )
1680
+ self._invalidate()
1681
+ return
1682
+
1683
+ # 运行时生效与刷新在后台 task 里;先记下已存盘的状态,
1684
+ # 刷新落地前再按一次 Space 才会按新状态反向切换,而不是重复同一个方向。
1685
+ tool["disabled"] = remote_name in names
1686
+ self._schedule_background(
1687
+ self._apply_mcp_disabled_tools(
1688
+ rows_by_alias=rows_by_alias,
1689
+ alias=alias,
1690
+ names=names,
1691
+ )
1692
+ )
1693
+
1694
+ async def _apply_mcp_disabled_tools(
1695
+ self,
1696
+ *,
1697
+ rows_by_alias: dict[str, dict[str, Any]],
1698
+ alias: str,
1699
+ names: list[str],
1700
+ ) -> None:
1701
+ """名单已存盘:通知运行时(不重连),再按 manager 的新状态刷新工具列表。"""
1702
+ error: str | None = None
1703
+ try:
1704
+ await self._session._agent.set_mcp_disabled_tools(alias, names)
1705
+ except Exception as exc:
1706
+ logger.warning("Failed to apply disabled MCP tools for '%s': %s", alias, exc)
1707
+ error = i18n(message.mcp_tool_toggle_apply_failed, error=exc)
1708
+
1709
+ refreshed_rows = self._collect_mcp_cached_rows()
1710
+ if refreshed_rows:
1711
+ # 原地更新:工具详情页与 server 详情页共用这份 rows,返回时看到的是新状态。
1712
+ rows_by_alias.update({str(r["alias"]): r for r in refreshed_rows})
1713
+
1714
+ # 用户已离开这个工具列表:不能把工具行刷进别的菜单。
1715
+ if self._mcp_tools_menu_alias != alias or self._ui_mode != UIMode.SELECTION:
1716
+ return
1717
+ row = rows_by_alias.get(alias)
1718
+ if row is None:
1719
+ return
1720
+ self._selection_ui.update_context_lines(self._mcp_tools_context_lines(row, error=error))
1721
+ self._selection_ui.update_options_preserve_selection(self._mcp_tools_menu_options(row))
1722
+ self._invalidate()
1723
+
1550
1724
  async def _open_mcp_tool_detail_menu_async(
1551
1725
  self,
1552
1726
  *,
@@ -1598,6 +1772,11 @@ class CommandsMixin:
1598
1772
  context_lines = [
1599
1773
  f"Tool name: {tool['remote_name']}",
1600
1774
  f"Full name: {tool['mapped_name']}",
1775
+ i18n(
1776
+ message.mcp_tool_status_disabled
1777
+ if tool.get("disabled")
1778
+ else message.mcp_tool_status_enabled
1779
+ ),
1601
1780
  "Description:",
1602
1781
  ]
1603
1782
  context_lines.extend(description.splitlines())