soothe-cli 1.1.0__tar.gz → 1.2.0b1__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 (152) hide show
  1. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/PKG-INFO +1 -1
  2. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/pyproject.toml +1 -1
  3. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/commands/command_registry.py +0 -6
  4. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/commands/slash_commands.py +0 -6
  5. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/commands/subagent_routing.py +0 -2
  6. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/presentation/subagent_task_display.py +1 -1
  7. soothe_cli-1.2.0b1/src/soothe_cli/tui/widgets/messages/cognition_reason.py +176 -0
  8. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/ux/subagent_wire_display.py +1 -2
  9. soothe_cli-1.1.0/src/soothe_cli/tui/widgets/messages/cognition_reason.py +0 -85
  10. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/.gitignore +0 -0
  11. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/README.md +0 -0
  12. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/__init__.py +0 -0
  13. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/_cli_context.py +0 -0
  14. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/_env_vars.py +0 -0
  15. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/_version.py +0 -0
  16. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/card_wire.py +0 -0
  17. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/__init__.py +0 -0
  18. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/commands/__init__.py +0 -0
  19. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/commands/config_cmd.py +0 -0
  20. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/commands/cron_cmd.py +0 -0
  21. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/commands/loop_cmd.py +0 -0
  22. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/commands/run_cmd.py +0 -0
  23. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/commands/status_cmd.py +0 -0
  24. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/execution/__init__.py +0 -0
  25. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/execution/daemon.py +0 -0
  26. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/execution/daemon_errors.py +0 -0
  27. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/execution/headless.py +0 -0
  28. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/execution/headless_renderer.py +0 -0
  29. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/execution/launcher.py +0 -0
  30. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/main.py +0 -0
  31. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/cli/soothecli.py +0 -0
  32. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/commands/__init__.py +0 -0
  33. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/commands/binding.py +0 -0
  34. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/commands/command_router.py +0 -0
  35. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/config/__init__.py +0 -0
  36. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/config/cli_config.py +0 -0
  37. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/config/loader.py +0 -0
  38. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/config/logging_setup.py +0 -0
  39. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/__init__.py +0 -0
  40. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/card.py +0 -0
  41. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/card_binder.py +0 -0
  42. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/markdown_theme.py +0 -0
  43. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/media_utils.py +0 -0
  44. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/mermaid_render.py +0 -0
  45. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/path_utils.py +0 -0
  46. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/preview_limits.py +0 -0
  47. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/shell_color.py +0 -0
  48. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/spinner_labels.py +0 -0
  49. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/text_extract.py +0 -0
  50. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/theme.py +0 -0
  51. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/tips.py +0 -0
  52. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/tool_display.py +0 -0
  53. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/display/unicode_security.py +0 -0
  54. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/loops/__init__.py +0 -0
  55. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/loops/sessions.py +0 -0
  56. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/model_config.py +0 -0
  57. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/project_utils.py +0 -0
  58. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/__init__.py +0 -0
  59. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/headless/processor.py +0 -0
  60. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/headless/processor_state.py +0 -0
  61. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/parse/tool_call_resolution.py +0 -0
  62. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/policy/tui_trace_log.py +0 -0
  63. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/presentation/duration_format.py +0 -0
  64. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/presentation/engine.py +0 -0
  65. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/presentation/id_format.py +0 -0
  66. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/presentation/renderer_base.py +0 -0
  67. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/presentation/renderer_protocol.py +0 -0
  68. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/presentation/step_id_format.py +0 -0
  69. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/state/file_tracker.py +0 -0
  70. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/state/session_stats.py +0 -0
  71. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/state/step_router.py +0 -0
  72. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/state/stream_accumulator.py +0 -0
  73. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/token_events_debug.py +0 -0
  74. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/token_usage.py +0 -0
  75. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/transport/session.py +0 -0
  76. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/turn/prepare.py +0 -0
  77. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/wire/chunk_filter.py +0 -0
  78. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/wire/message_text.py +0 -0
  79. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/runtime/wire/messages.py +0 -0
  80. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/__init__.py +0 -0
  81. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/_console_impl.py +0 -0
  82. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/bootstrap.py +0 -0
  83. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/core.py +0 -0
  84. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/glyphs.py +0 -0
  85. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/provider.py +0 -0
  86. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/shell_allow.py +0 -0
  87. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/skills_dirs.py +0 -0
  88. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/settings/stream_config.py +0 -0
  89. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/__init__.py +0 -0
  90. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/__init__.py +0 -0
  91. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_app.py +0 -0
  92. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_clarification.py +0 -0
  93. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_entrypoints.py +0 -0
  94. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_execution.py +0 -0
  95. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_history.py +0 -0
  96. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_messages_mixin.py +0 -0
  97. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_model.py +0 -0
  98. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_model_params.py +0 -0
  99. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_startup.py +0 -0
  100. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_terminal.py +0 -0
  101. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_theme_prefs.py +0 -0
  102. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_types.py +0 -0
  103. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/_ui.py +0 -0
  104. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/app/app.tcss +0 -0
  105. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/composer_mode.py +0 -0
  106. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/file_change_notify.py +0 -0
  107. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/file_change_renderers.py +0 -0
  108. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/input.py +0 -0
  109. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/skills/__init__.py +0 -0
  110. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/skills/invocation.py +0 -0
  111. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/skills/load.py +0 -0
  112. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/textual_adapter.py +0 -0
  113. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/__init__.py +0 -0
  114. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/_links.py +0 -0
  115. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/autocomplete.py +0 -0
  116. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/chat_input.py +0 -0
  117. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/clipboard.py +0 -0
  118. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/context_data.py +0 -0
  119. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/context_viewer.py +0 -0
  120. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/diff.py +0 -0
  121. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/editor.py +0 -0
  122. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/file_change_preview.py +0 -0
  123. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/help_screen.py +0 -0
  124. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/history.py +0 -0
  125. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/loading.py +0 -0
  126. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/loop_selector.py +0 -0
  127. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/mcp_viewer.py +0 -0
  128. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/message_store.py +0 -0
  129. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/__init__.py +0 -0
  130. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/_helpers.py +0 -0
  131. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/app.py +0 -0
  132. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/assistant.py +0 -0
  133. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/cognition_goal_tree.py +0 -0
  134. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/cognition_step.py +0 -0
  135. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/cognition_step_activity.py +0 -0
  136. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/diff_message.py +0 -0
  137. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/error.py +0 -0
  138. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/skill.py +0 -0
  139. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/structured_ask_user.py +0 -0
  140. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/messages/user.py +0 -0
  141. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/model_selector.py +0 -0
  142. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/notification_settings.py +0 -0
  143. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/pinned_goal_bar.py +0 -0
  144. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/plan_quick_view_overlay.py +0 -0
  145. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/queued_goals_bar.py +0 -0
  146. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/router_profile_selector.py +0 -0
  147. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/status.py +0 -0
  148. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/theme_selector.py +0 -0
  149. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/tui/widgets/welcome.py +0 -0
  150. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/update_check.py +0 -0
  151. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/ux/__init__.py +0 -0
  152. {soothe_cli-1.1.0 → soothe_cli-1.2.0b1}/src/soothe_cli/ux/subagent_progress.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: soothe-cli
3
- Version: 1.1.0
3
+ Version: 1.2.0-beta.1
4
4
  Summary: Soothe CLI client - communicates with daemon via WebSocket
5
5
  Project-URL: Homepage, https://github.com/mirasoth/soothe
6
6
  Project-URL: Documentation, https://soothe.readthedocs.io
@@ -76,7 +76,7 @@ docstring-code-format = true
76
76
 
77
77
  [tool.hatch.version]
78
78
  path = "../../VERSION"
79
- pattern = "^(?P<version>[0-9]+\\.[0-9]+\\.[0-9]+)$"
79
+ pattern = "^(?P<version>[0-9]+\\.[0-9]+\\.[0-9]+.*)"
80
80
 
81
81
  [tool.mypy]
82
82
  python_version = "3.12"
@@ -132,12 +132,6 @@ COMMANDS: tuple[SlashCommand, ...] = (
132
132
  bypass_tier=BypassTier.QUEUED,
133
133
  enter_action=EnterAction.COMPLETE,
134
134
  ),
135
- SlashCommand(
136
- name="/academic_research",
137
- description="Route prompt to academic_research subagent (usage: /academic_research <query>)",
138
- bypass_tier=BypassTier.QUEUED,
139
- enter_action=EnterAction.COMPLETE,
140
- ),
141
135
  SlashCommand(
142
136
  name="/browser_use",
143
137
  description="Route prompt to browser_use subagent (usage: /browser_use <task>)",
@@ -268,12 +268,6 @@ COMMANDS: dict[str, dict[str, Any]] = {
268
268
  "description": "Route query to Deep Research subagent",
269
269
  "requires_query": True,
270
270
  },
271
- "/academic_research": {
272
- "location": "daemon",
273
- "type": "routing",
274
- "description": "Route query to Academic Research subagent",
275
- "requires_query": True,
276
- },
277
271
  "/browser_use": {
278
272
  "location": "daemon",
279
273
  "type": "routing",
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
  # Display names for known soothe core subagents.
6
6
  SUBAGENT_DISPLAY_NAMES: dict[str, str] = {
7
7
  "deep_research": "Deep Research",
8
- "academic_research": "Academic Research",
9
8
  "browser_use": "Browser",
10
9
  }
11
10
 
@@ -14,7 +13,6 @@ SUBAGENT_DISPLAY_NAMES: dict[str, str] = {
14
13
  # Intake-only specialists (601) must stay here so slash sets preferred_subagent.
15
14
  # ``/plan`` is now handled separately by command_router (interaction_mode=plan).
16
15
  SUBAGENT_SLASH_ROUTE_IDS: tuple[str, ...] = (
17
- "academic_research",
18
16
  "deep_research",
19
17
  "browser_use",
20
18
  )
@@ -92,7 +92,7 @@ def format_subagent_task_assistant_for_display(
92
92
  """
93
93
  agent = (subagent_type or "").strip().lower()
94
94
  text = raw
95
- if agent in ("deep_research", "academic_research"):
95
+ if agent == "deep_research":
96
96
  stripped = text.strip()
97
97
  internal_present = any(
98
98
  _is_deep_research_internal_json_object(obj)
@@ -0,0 +1,176 @@
1
+ """Cognition reason (plan) message widget."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ from textual.containers import Horizontal, Vertical
8
+ from textual.content import Content
9
+ from textual.widgets import Static
10
+
11
+ from soothe_cli.display.card import _assemble_card_header, _card_dot_prefix_content
12
+ from soothe_cli.display.markdown_theme import ThemedMarkdownRenderer, resolve_markdown_theme_parts
13
+
14
+ if TYPE_CHECKING:
15
+ from textual.app import ComposeResult
16
+
17
+
18
+ class _ReasonMarkdownBody(Static):
19
+ """Static body that renders reason text as themed Markdown."""
20
+
21
+ DEFAULT_CSS = """
22
+ _ReasonMarkdownBody {
23
+ padding: 0;
24
+ margin: 0;
25
+ width: 1fr;
26
+ height: auto;
27
+ }
28
+ """
29
+
30
+
31
+ class CognitionReasonMessage(Vertical):
32
+ """Single card for plan assessment and plan reasoning.
33
+
34
+ Header uses the same stateful prefix glyph plus foreground body as `CognitionStepMessage`.
35
+
36
+ The body is rendered as themed Markdown (headings, lists, code spans,
37
+ emphasis) via the active markdown theme preset, so multi-line reasoning
38
+ with Markdown formatting (e.g. numbered subtask lists) renders properly
39
+ instead of as a single plain-text line.
40
+ """
41
+
42
+ ALLOW_SELECT = True
43
+
44
+ DEFAULT_CSS = """
45
+ CognitionReasonMessage {
46
+ height: auto;
47
+ padding: 0 1;
48
+ margin: 0 0 1 0;
49
+ background: transparent;
50
+ }
51
+
52
+ CognitionReasonMessage .cognition-plan-row {
53
+ height: auto;
54
+ width: 1fr;
55
+ }
56
+
57
+ CognitionReasonMessage .cognition-plan-dot {
58
+ width: auto;
59
+ height: auto;
60
+ padding: 0;
61
+ margin: 0;
62
+ }
63
+
64
+ CognitionReasonMessage .cognition-plan-header {
65
+ height: auto;
66
+ margin: 0;
67
+ color: $foreground;
68
+ padding: 0;
69
+ width: 1fr;
70
+ }
71
+ """
72
+
73
+ def __init__(
74
+ self,
75
+ *,
76
+ status: str,
77
+ iteration: int,
78
+ plan_action: str = "new",
79
+ assessment_reasoning: str = "",
80
+ plan_reasoning: str = "",
81
+ **kwargs: Any,
82
+ ) -> None:
83
+ """Initialize a plan-reason card.
84
+
85
+ Args:
86
+ status: Plan status (continue, replan, done).
87
+ iteration: Agent-loop iteration index.
88
+ plan_action: `keep` or `new` (internal execution strategy, not displayed).
89
+ assessment_reasoning: Phase-1 status justification from plan-assess.
90
+ plan_reasoning: Optional strategy/summary line (e.g. step completion).
91
+ **kwargs: Passed to `Vertical`.
92
+ """
93
+ super().__init__(**kwargs)
94
+ self._status = status
95
+ self._iteration = iteration
96
+ self._plan_action = plan_action if plan_action in ("keep", "new") else ""
97
+ self._assessment_reasoning = assessment_reasoning.strip()
98
+ self._plan_reasoning = plan_reasoning.strip()
99
+ # Cached markdown theme parts (entry, colors, code_theme) — resolved
100
+ # once on first markdown render and reused for the widget's lifetime.
101
+ self._cached_theme_parts: tuple[Any, Any, str] | None = None
102
+ self._dot_widget: Static | None = None
103
+ self._body_widget: _ReasonMarkdownBody | None = None
104
+
105
+ def _plan_body_text(self) -> str:
106
+ """Assemble the plan body text from assessment and plan reasoning."""
107
+ parts: list[str] = []
108
+ if self._assessment_reasoning:
109
+ parts.append(self._assessment_reasoning)
110
+ if self._plan_reasoning:
111
+ parts.append(self._plan_reasoning)
112
+ if len(parts) == 2:
113
+ first = parts[0]
114
+ if not first.endswith((".", "!", "?")):
115
+ first = f"{first}."
116
+ return f"{first} {parts[1]}"
117
+ if parts:
118
+ return parts[0]
119
+ return ""
120
+
121
+ def _plan_header_content(self) -> Content:
122
+ """Build the header Content (prefix glyph + plain body).
123
+
124
+ Kept for backward compatibility with tests that inspect the header
125
+ content directly. The live widget renders the body as Markdown in
126
+ :meth:`_render_body`; this method returns the plain-text equivalent.
127
+ """
128
+ body = self._plan_body_text()
129
+ return _assemble_card_header(self, body, status=self._status)
130
+
131
+ def _get_theme_parts(self) -> tuple[Any, Any, str]:
132
+ """Resolve and cache markdown theme parts for repeated renders."""
133
+ if self._cached_theme_parts is None:
134
+ self._cached_theme_parts = resolve_markdown_theme_parts(self)
135
+ return self._cached_theme_parts
136
+
137
+ def _render_body(self) -> Any:
138
+ """Render the plan body as themed Markdown.
139
+
140
+ Falls back to plain styled Content when Markdown construction fails,
141
+ so a parse error never blanks out the card.
142
+ """
143
+ text = self._plan_body_text()
144
+ if not text:
145
+ return Content("")
146
+ try:
147
+ entry, colors, code_theme = self._get_theme_parts()
148
+ return ThemedMarkdownRenderer(
149
+ text,
150
+ entry=entry,
151
+ colors=colors,
152
+ code_theme=code_theme,
153
+ )
154
+ except Exception: # noqa: BLE001 # Degrade gracefully on parse errors.
155
+ return _assemble_card_header(self, text, status=self._status)
156
+
157
+ def _refresh_dot(self) -> None:
158
+ if self._dot_widget is None:
159
+ return
160
+ self._dot_widget.update(_card_dot_prefix_content(self, self._status))
161
+
162
+ def on_mount(self) -> None:
163
+ """Wire child widget references and render initial content."""
164
+ self._dot_widget = self.query_one("#cognition-plan-dot", Static)
165
+ self._body_widget = self.query_one("#cognition-plan-header", _ReasonMarkdownBody)
166
+ self._refresh_dot()
167
+ if self._body_widget is not None:
168
+ self._body_widget.update(self._render_body())
169
+
170
+ def compose(self) -> ComposeResult:
171
+ """Compose inline prefix glyph and markdown body on one row."""
172
+ with Horizontal(classes="cognition-plan-row"):
173
+ yield Static("", classes="cognition-plan-dot", id="cognition-plan-dot")
174
+ yield _ReasonMarkdownBody(
175
+ "", markup=False, classes="cognition-plan-header", id="cognition-plan-header"
176
+ )
@@ -76,8 +76,7 @@ def subagent_wire_row_params(
76
76
  if rc or st:
77
77
  tail = f"{rc} hits, {st} sources"
78
78
  preview = f"{query} → {tail}" if query else tail
79
- tool_name = "AcademicSearch" if ".academic_research." in et else "WebSearch"
80
- return tool_name, {"query": preview or query}, "success", 0
79
+ return "WebSearch", {"query": preview or query}, "success", 0
81
80
  if et.endswith(".crawl.summary"):
82
81
  urls = int(data.get("urls_crawled", 0) or 0)
83
82
  success = int(data.get("success_count", 0) or 0)
@@ -1,85 +0,0 @@
1
- """Cognition reason (plan) message widget."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import TYPE_CHECKING, Any
6
-
7
- from textual.containers import Vertical
8
- from textual.content import Content
9
- from textual.widgets import Static
10
-
11
- from soothe_cli.display.card import _assemble_card_header
12
-
13
- if TYPE_CHECKING:
14
- from textual.app import ComposeResult
15
-
16
-
17
- class CognitionReasonMessage(Vertical):
18
- """Single card for plan assessment and plan reasoning.
19
-
20
- Header uses the same stateful prefix glyph plus foreground body as `CognitionStepMessage`.
21
- """
22
-
23
- ALLOW_SELECT = True
24
-
25
- DEFAULT_CSS = """
26
- CognitionReasonMessage {
27
- height: auto;
28
- padding: 0 1;
29
- margin: 0 0 1 0;
30
- background: transparent;
31
- }
32
-
33
- CognitionReasonMessage .cognition-plan-header {
34
- height: auto;
35
- margin: 0;
36
- color: $foreground;
37
- }
38
- """
39
-
40
- def __init__(
41
- self,
42
- *,
43
- status: str,
44
- iteration: int,
45
- plan_action: str = "new",
46
- assessment_reasoning: str = "",
47
- plan_reasoning: str = "",
48
- **kwargs: Any,
49
- ) -> None:
50
- """Initialize a plan-reason card.
51
-
52
- Args:
53
- status: Plan status (continue, replan, done).
54
- iteration: Agent-loop iteration index.
55
- plan_action: `keep` or `new` (internal execution strategy, not displayed).
56
- assessment_reasoning: Phase-1 status justification from plan-assess.
57
- plan_reasoning: Optional strategy/summary line (e.g. step completion).
58
- **kwargs: Passed to `Vertical`.
59
- """
60
- super().__init__(**kwargs)
61
- self._status = status
62
- self._iteration = iteration
63
- self._plan_action = plan_action if plan_action in ("keep", "new") else ""
64
- self._assessment_reasoning = assessment_reasoning.strip()
65
- self._plan_reasoning = plan_reasoning.strip()
66
-
67
- def _plan_header_content(self) -> Content:
68
- parts: list[str] = []
69
- if self._assessment_reasoning:
70
- parts.append(self._assessment_reasoning)
71
- if self._plan_reasoning:
72
- parts.append(self._plan_reasoning)
73
- if len(parts) == 2:
74
- first = parts[0]
75
- if not first.endswith((".", "!", "?")):
76
- first = f"{first}."
77
- body = f"{first} {parts[1]}"
78
- elif parts:
79
- body = parts[0]
80
- else:
81
- body = ""
82
- return _assemble_card_header(self, body, status=self._status)
83
-
84
- def compose(self) -> ComposeResult:
85
- yield Static(self._plan_header_content(), classes="cognition-plan-header")
File without changes
File without changes