soothe-cli 0.9.2__tar.gz → 0.9.5__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 (132) hide show
  1. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/PKG-INFO +2 -2
  2. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/pyproject.toml +1 -1
  3. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/commands/config_cmd.py +1 -1
  4. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/token_events_debug.py +1 -1
  5. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_execution.py +2 -2
  6. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_model.py +4 -4
  7. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_module_init.py +12 -10
  8. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/config.py +17 -16
  9. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/markdown_theme.py +6 -5
  10. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/model_config.py +38 -4
  11. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/theme.py +6 -6
  12. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/update_check.py +7 -6
  13. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/model_selector.py +2 -2
  14. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/notification_settings.py +3 -3
  15. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/.gitignore +0 -0
  16. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/README.md +0 -0
  17. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/__init__.py +0 -0
  18. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/__init__.py +0 -0
  19. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/commands/__init__.py +0 -0
  20. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/commands/autopilot_cmd.py +0 -0
  21. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/commands/cron_cmd.py +0 -0
  22. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/commands/loop_cmd.py +0 -0
  23. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/commands/run_cmd.py +0 -0
  24. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/commands/status_cmd.py +0 -0
  25. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/execution/__init__.py +0 -0
  26. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/execution/daemon.py +0 -0
  27. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/execution/daemon_errors.py +0 -0
  28. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/execution/headless.py +0 -0
  29. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/execution/headless_renderer.py +0 -0
  30. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/execution/launcher.py +0 -0
  31. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/cli/main.py +0 -0
  32. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/config/__init__.py +0 -0
  33. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/config/cli_config.py +0 -0
  34. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/config/loader.py +0 -0
  35. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/config/logging_setup.py +0 -0
  36. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/__init__.py +0 -0
  37. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/headless/processor.py +0 -0
  38. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/headless/processor_state.py +0 -0
  39. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/parse/message_processing.py +0 -0
  40. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/parse/tool_call_resolution.py +0 -0
  41. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/parse/tool_result.py +0 -0
  42. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/policy/display_policy.py +0 -0
  43. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/policy/essential_events.py +0 -0
  44. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/policy/tui_trace_log.py +0 -0
  45. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/presentation/duration_format.py +0 -0
  46. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/presentation/engine.py +0 -0
  47. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/presentation/id_format.py +0 -0
  48. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/presentation/renderer_base.py +0 -0
  49. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/presentation/renderer_protocol.py +0 -0
  50. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/presentation/subagent_task_display.py +0 -0
  51. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/state/file_tracker.py +0 -0
  52. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/state/session_stats.py +0 -0
  53. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/state/step_router.py +0 -0
  54. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/state/stream_accumulator.py +0 -0
  55. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/state/transcript.py +0 -0
  56. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/token_usage.py +0 -0
  57. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/transport/session.py +0 -0
  58. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/turn/pipeline.py +0 -0
  59. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/turn/prepare.py +0 -0
  60. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/wire/chunk_filter.py +0 -0
  61. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/wire/message_text.py +0 -0
  62. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/runtime/wire/messages.py +0 -0
  63. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/__init__.py +0 -0
  64. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/_cli_context.py +0 -0
  65. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/_env_vars.py +0 -0
  66. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/_version.py +0 -0
  67. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/__init__.py +0 -0
  68. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_app.py +0 -0
  69. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_history.py +0 -0
  70. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_messages_mixin.py +0 -0
  71. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_startup.py +0 -0
  72. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/_ui.py +0 -0
  73. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/app/app.tcss +0 -0
  74. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/binding.py +0 -0
  75. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/command_registry.py +0 -0
  76. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/commands/__init__.py +0 -0
  77. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/commands/command_router.py +0 -0
  78. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/commands/slash_commands.py +0 -0
  79. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/commands/subagent_routing.py +0 -0
  80. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/file_change_notify.py +0 -0
  81. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/file_change_renderers.py +0 -0
  82. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/hooks.py +0 -0
  83. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/input.py +0 -0
  84. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/media_utils.py +0 -0
  85. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/path_utils.py +0 -0
  86. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/preview_limits.py +0 -0
  87. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/project_utils.py +0 -0
  88. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/sessions.py +0 -0
  89. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/shell_color.py +0 -0
  90. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/skills/__init__.py +0 -0
  91. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/skills/invocation.py +0 -0
  92. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/skills/load.py +0 -0
  93. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/spinner_labels.py +0 -0
  94. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/textual_adapter.py +0 -0
  95. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/tips.py +0 -0
  96. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/tool_display.py +0 -0
  97. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/unicode_security.py +0 -0
  98. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/__init__.py +0 -0
  99. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/_links.py +0 -0
  100. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/autocomplete.py +0 -0
  101. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/chat_input.py +0 -0
  102. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/clipboard.py +0 -0
  103. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/context_data.py +0 -0
  104. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/context_viewer.py +0 -0
  105. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/diff.py +0 -0
  106. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/editor.py +0 -0
  107. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/file_change_preview.py +0 -0
  108. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/help_screen.py +0 -0
  109. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/history.py +0 -0
  110. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/loading.py +0 -0
  111. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/loop_selector.py +0 -0
  112. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/mcp_viewer.py +0 -0
  113. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/message_store.py +0 -0
  114. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/__init__.py +0 -0
  115. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/_helpers.py +0 -0
  116. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/app.py +0 -0
  117. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/assistant.py +0 -0
  118. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/clarification.py +0 -0
  119. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/cognition_goal_tree.py +0 -0
  120. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/cognition_reason.py +0 -0
  121. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/cognition_step.py +0 -0
  122. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/cognition_step_activity.py +0 -0
  123. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/cognition_subagent.py +0 -0
  124. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/diff_message.py +0 -0
  125. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/error.py +0 -0
  126. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/skill.py +0 -0
  127. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/messages/user.py +0 -0
  128. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/plan_quick_view_overlay.py +0 -0
  129. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/router_profile_selector.py +0 -0
  130. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/status.py +0 -0
  131. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/theme_selector.py +0 -0
  132. {soothe_cli-0.9.2 → soothe_cli-0.9.5}/src/soothe_cli/tui/widgets/welcome.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soothe-cli
3
- Version: 0.9.2
3
+ Version: 0.9.5
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
@@ -22,7 +22,7 @@ Requires-Dist: pillow<12.0.0,>=10.0.0
22
22
  Requires-Dist: python-dotenv<2.0.0,>=1.0.0
23
23
  Requires-Dist: pyyaml<7.0.0,>=6.0.0
24
24
  Requires-Dist: rich<15.0.0,>=13.0.0
25
- Requires-Dist: soothe-client-python<1.0.0,>=0.10.0
25
+ Requires-Dist: soothe-client-python<2.0.0,>=1.0.4
26
26
  Requires-Dist: soothe-sdk<2.0.0,>=1.0.2
27
27
  Requires-Dist: textual<10.0.0,>=8.0.0
28
28
  Requires-Dist: typer<2.0.0,>=0.9.0
@@ -24,7 +24,7 @@ classifiers = [
24
24
  ]
25
25
  dependencies = [
26
26
  "soothe-sdk>=1.0.2,<2.0.0", # events/display/wire contracts
27
- "soothe-client-python>=0.10.0,<1.0.0", # WebSocket transport client
27
+ "soothe-client-python>=1.0.4,<2.0.0", # WebSocket transport client
28
28
  "typer>=0.9.0,<2.0.0", # CLI framework
29
29
  "textual>=8.0.0,<10.0.0", # TUI framework
30
30
  "rich>=13.0.0,<15.0.0", # Console output
@@ -51,7 +51,7 @@ def config_reload(
51
51
  """Trigger config hot-reload on the running daemon.
52
52
 
53
53
  Sends a config_reload RPC request to the daemon, which triggers immediate
54
- reload of watched config files (config.yml and daemon.yml). Requires the
54
+ reload of watched config files (nano.yml and daemon.yml). Requires the
55
55
  daemon to have hot-reload enabled via daemon.enable_config_reload().
56
56
 
57
57
  Examples:
@@ -1,6 +1,6 @@
1
1
  """Debug tracing for loop token events in the CLI TUI.
2
2
 
3
- Enable with ``logging_level: DEBUG`` in CLI config (``~/.soothe/config.yml``)
3
+ Enable with ``logging_level: DEBUG`` in CLI config (``~/.soothe/config/cli.yml``)
4
4
  or ``SOOTHE_LOG_LEVEL=DEBUG``. Grep ``cli.log`` for ``[token-events]``.
5
5
  """
6
6
 
@@ -664,7 +664,7 @@ class _ExecutionMixin:
664
664
  )
665
665
  return
666
666
 
667
- # Reload user themes from config.yml and re-register with Textual
667
+ # Reload user themes from cli.yml and re-register with Textual
668
668
  theme_reload_ok = True
669
669
  try:
670
670
  theme.reload_registry()
@@ -683,7 +683,7 @@ class _ExecutionMixin:
683
683
  if theme_reload_ok:
684
684
  report += "\nTheme registry reloaded."
685
685
  else:
686
- report += "\nTheme registry reload failed. Check config.yml for errors."
686
+ report += "\nTheme registry reload failed. Check cli.yml for errors."
687
687
  await self._mount_message(AppMessage(report))
688
688
 
689
689
  if self._daemon_session is not None:
@@ -106,7 +106,7 @@ class _ModelMixin:
106
106
  if not all_models:
107
107
  await self._mount_message(
108
108
  ErrorMessage(
109
- "Daemon returned no models. Check providers and `models:` lists in the daemon host config.yml."
109
+ "Daemon returned no models. Check providers and `models:` lists in the daemon host nano.yml."
110
110
  ),
111
111
  )
112
112
  return
@@ -665,7 +665,7 @@ class _ModelMixin:
665
665
  *,
666
666
  extra_kwargs: dict[str, Any] | None = None,
667
667
  ) -> None:
668
- """Switch model for the current loop without changing `config.yml`.
668
+ """Switch model for the current loop without changing `nano.yml`.
669
669
 
670
670
  The override is sent on each websocket ``input`` (resolved on the daemon
671
671
  host). Global ``settings`` and on-disk defaults are not updated; use
@@ -736,7 +736,7 @@ class _ModelMixin:
736
736
  await self._mount_message(
737
737
  AppMessage(
738
738
  f"Switched this loop to {display} for daemon turns "
739
- f"(session only; daemon host default in config.yml unchanged).",
739
+ f"(session only; daemon host default in nano.yml unchanged).",
740
740
  ),
741
741
  )
742
742
  logger.info("Model override set to %s for daemon-backed TUI session", display)
@@ -750,7 +750,7 @@ class _ModelMixin:
750
750
  async def _set_default_model(self, model_spec: str) -> None:
751
751
  """Set the default model in config without switching the current session.
752
752
 
753
- Updates `[models].default` in `~/SOOTHE_HOME/config.yml` so that
753
+ Updates `[models].default` in daemon `nano.yml` so that
754
754
  future CLI launches use this model. Does not affect the running session.
755
755
 
756
756
  Args:
@@ -104,12 +104,13 @@ def _load_theme_preference() -> str:
104
104
  import yaml
105
105
 
106
106
  try:
107
- from soothe_cli.tui.model_config import DEFAULT_CONFIG_PATH
107
+ from soothe_cli.tui.model_config import resolve_cli_config_path
108
108
 
109
- if not DEFAULT_CONFIG_PATH.exists():
109
+ config_path = resolve_cli_config_path()
110
+ if not config_path.exists():
110
111
  return theme.DEFAULT_THEME
111
112
 
112
- with DEFAULT_CONFIG_PATH.open("rb") as f:
113
+ with config_path.open("rb") as f:
113
114
  data = yaml.safe_load(f)
114
115
  except (yaml.YAMLError, PermissionError, OSError) as exc:
115
116
  logger.warning("Could not read config for theme preference: %s", exc)
@@ -127,7 +128,7 @@ def _load_theme_preference() -> str:
127
128
 
128
129
 
129
130
  def save_theme_preference(name: str) -> bool:
130
- """Persist theme preference to `~/SOOTHE_HOME/config/config.yml`.
131
+ """Persist theme preference to `~/SOOTHE_HOME/config/cli.yml`.
131
132
 
132
133
  Args:
133
134
  name: Textual theme name to save.
@@ -145,11 +146,12 @@ def save_theme_preference(name: str) -> bool:
145
146
  try:
146
147
  import yaml
147
148
 
148
- from soothe_cli.tui.model_config import DEFAULT_CONFIG_PATH
149
+ from soothe_cli.tui.model_config import resolve_cli_config_path
149
150
 
150
- DEFAULT_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
151
- if DEFAULT_CONFIG_PATH.exists():
152
- with DEFAULT_CONFIG_PATH.open("r") as f:
151
+ config_path = resolve_cli_config_path()
152
+ config_path.parent.mkdir(parents=True, exist_ok=True)
153
+ if config_path.exists():
154
+ with config_path.open("r") as f:
153
155
  data = yaml.safe_load(f)
154
156
  else:
155
157
  data = {}
@@ -158,11 +160,11 @@ def save_theme_preference(name: str) -> bool:
158
160
  data["ui"] = {}
159
161
  data["ui"]["theme"] = name
160
162
 
161
- fd, tmp_path = tempfile.mkstemp(dir=DEFAULT_CONFIG_PATH.parent, suffix=".tmp")
163
+ fd, tmp_path = tempfile.mkstemp(dir=config_path.parent, suffix=".tmp")
162
164
  try:
163
165
  with os.fdopen(fd, "w") as f:
164
166
  yaml.safe_dump(data, f)
165
- Path(tmp_path).replace(DEFAULT_CONFIG_PATH)
167
+ Path(tmp_path).replace(config_path)
166
168
  except BaseException:
167
169
  with contextlib.suppress(OSError):
168
170
  Path(tmp_path).unlink()
@@ -642,7 +642,7 @@ def parse_shell_allow_list(allow_list_str: str | None) -> list[str] | None:
642
642
 
643
643
 
644
644
  def _read_config_yaml_skills_dirs() -> list[str] | None:
645
- """Read `[skills].extra_allowed_dirs` from `SOOTHE_HOME/config/config.yml`.
645
+ """Read `[skills].extra_allowed_dirs` from `SOOTHE_HOME/config/cli.yml`.
646
646
 
647
647
  Returns:
648
648
  List of path strings, or `None` if the key is absent or the file
@@ -650,17 +650,18 @@ def _read_config_yaml_skills_dirs() -> list[str] | None:
650
650
  """
651
651
  import yaml
652
652
 
653
- from soothe_cli.tui.model_config import DEFAULT_CONFIG_PATH
653
+ from soothe_cli.tui.model_config import resolve_cli_config_path
654
654
 
655
655
  try:
656
- with DEFAULT_CONFIG_PATH.open("r") as f:
656
+ config_path = resolve_cli_config_path()
657
+ with config_path.open("r") as f:
657
658
  data = yaml.safe_load(f)
658
659
  except FileNotFoundError:
659
660
  return None
660
661
  except (PermissionError, OSError, yaml.YAMLError):
661
662
  logger.warning(
662
663
  "Could not read skills config from %s",
663
- DEFAULT_CONFIG_PATH,
664
+ resolve_cli_config_path(),
664
665
  exc_info=True,
665
666
  )
666
667
  return None
@@ -676,7 +677,7 @@ def _parse_extra_skills_dirs(
676
677
  env_raw: str | None,
677
678
  config_yaml_dirs: list[str] | None = None,
678
679
  ) -> list[Path] | None:
679
- """Merge extra skill directories from env var and config.yml.
680
+ """Merge extra skill directories from env var and cli.yml.
680
681
 
681
682
  Extra skills directories extend the containment allowlist used by
682
683
  `load_skill_content` to validate that a resolved skill path lives inside a
@@ -687,13 +688,13 @@ def _parse_extra_skills_dirs(
687
688
  containment check.
688
689
 
689
690
  The env var (`SOOTHE_EXTRA_SKILLS_DIRS`, colon-separated) takes
690
- precedence: when set, `config.yml` values are ignored.
691
+ precedence: when set, `cli.yml` values are ignored.
691
692
 
692
693
  Args:
693
694
  env_raw: Value of `SOOTHE_EXTRA_SKILLS_DIRS` (colon-separated), or
694
695
  `None` if unset.
695
696
  config_yaml_dirs: List of path strings from
696
- `[skills].extra_allowed_dirs` in `SOOTHE_HOME/config/config.yml`.
697
+ `[skills].extra_allowed_dirs` in `SOOTHE_HOME/config/cli.yml`.
697
698
 
698
699
  Returns:
699
700
  List of resolved `Path` objects, or `None` if not configured.
@@ -771,7 +772,7 @@ class Settings:
771
772
  in `load_skill_content`.
772
773
 
773
774
  Set via `SOOTHE_EXTRA_SKILLS_DIRS` env var (colon-separated) or
774
- `[skills].extra_allowed_dirs` in `SOOTHE_HOME/config/config.yml`.
775
+ `[skills].extra_allowed_dirs` in `SOOTHE_HOME/config/cli.yml`.
775
776
  """
776
777
 
777
778
  @classmethod
@@ -810,7 +811,7 @@ class Settings:
810
811
  shell_allow_list_str = os.environ.get(SHELL_ALLOW_LIST)
811
812
  shell_allow_list = parse_shell_allow_list(shell_allow_list_str)
812
813
 
813
- # Parse extra skill containment roots from env var or config.yml.
814
+ # Parse extra skill containment roots from env var or cli.yml.
814
815
  # These extend the path allowlist for load_skill_content but do not
815
816
  # add new skill discovery locations.
816
817
  extra_skills_dirs = _parse_extra_skills_dirs(
@@ -1396,7 +1397,7 @@ def _apply_openrouter_defaults(kwargs: dict[str, Any]) -> None:
1396
1397
  (see https://openrouter.ai/docs/app-attribution).
1397
1398
 
1398
1399
  Users can override either value provider-wide or per-model in
1399
- `SOOTHE_HOME/config/config.yml`:
1400
+ `SOOTHE_HOME/config/cli.yml`:
1400
1401
 
1401
1402
  ```yaml
1402
1403
  # Provider-wide
@@ -1421,7 +1422,7 @@ def _get_provider_kwargs(provider: str, *, model_name: str | None = None) -> dic
1421
1422
  """Get provider-specific kwargs from the config file.
1422
1423
 
1423
1424
  Reads `base_url`, `api_key_env`, and the `params` table from the user's
1424
- `config.yml` for the given provider.
1425
+ `cli.yml` for the given provider.
1425
1426
 
1426
1427
  When `model_name` is provided, per-model overrides from the `params`
1427
1428
  sub-table are shallow-merged on top.
@@ -1447,7 +1448,7 @@ def _get_provider_kwargs(provider: str, *, model_name: str | None = None) -> dic
1447
1448
  api_key_env = PROVIDER_API_KEY_ENV.get(provider)
1448
1449
  if api_key_env:
1449
1450
  logger.debug(
1450
- "No api_key_env in config.yml for '%s'; using hardcoded provider env var",
1451
+ "No api_key_env in nano.yml for '%s'; using hardcoded provider env var",
1451
1452
  provider,
1452
1453
  )
1453
1454
  if api_key_env:
@@ -1625,7 +1626,7 @@ def _apply_profile_overrides(
1625
1626
  overrides: Key/value pairs to merge into the profile.
1626
1627
  model_name: Model name used in log/error messages.
1627
1628
  label: Human-readable source label for messages
1628
- (e.g., `"config.yml"`, `"CLI --profile-override"`).
1629
+ (e.g., `"cli.yml"`, `"CLI --profile-override"`).
1629
1630
  raise_on_failure: When `True`, raise `ModelConfigError` instead
1630
1631
  of logging a warning if assignment fails.
1631
1632
 
@@ -1759,7 +1760,7 @@ def create_model(
1759
1760
 
1760
1761
  resolved_provider = provider or getattr(model, "_model_provider", provider)
1761
1762
 
1762
- # Apply profile overrides from config.yml (e.g., max_input_tokens)
1763
+ # Apply profile overrides from cli.yml (e.g., max_input_tokens)
1763
1764
  if provider:
1764
1765
  config_profile_overrides = config.get_profile_overrides(provider, model_name=model_name)
1765
1766
  if config_profile_overrides:
@@ -1767,10 +1768,10 @@ def create_model(
1767
1768
  model,
1768
1769
  config_profile_overrides,
1769
1770
  model_name,
1770
- label=f"config.yml (provider '{provider}')",
1771
+ label=f"cli.yml (provider '{provider}')",
1771
1772
  )
1772
1773
 
1773
- # CLI --profile-override takes highest priority (on top of config.yml)
1774
+ # CLI --profile-override takes highest priority (on top of cli.yml)
1774
1775
  if profile_overrides:
1775
1776
  _apply_profile_overrides(
1776
1777
  model,
@@ -2,8 +2,8 @@
2
2
 
3
3
  Display labels and stable IDs follow the same pattern as ``theme.ThemeEntry``.
4
4
  Users configure via ``--markdown-theme`` or ``ui.markdown_theme`` in the
5
- **CLI client** preferences file ``~/SOOTHE_HOME/config/config.yml`` (TUI only —
6
- not the daemon ``config/config.yml`` in the repo).
5
+ **CLI client** preferences file ``~/SOOTHE_HOME/config/cli.yml`` (TUI only —
6
+ not the daemon ``nano.yml`` / ``soothe.yml``).
7
7
  """
8
8
 
9
9
  from __future__ import annotations
@@ -134,12 +134,13 @@ def load_markdown_theme_preference() -> str:
134
134
  """Load saved markdown theme from the CLI TUI preferences file."""
135
135
  import yaml
136
136
 
137
- from soothe_cli.tui.model_config import DEFAULT_CONFIG_PATH
137
+ from soothe_cli.tui.model_config import resolve_cli_config_path
138
138
 
139
139
  try:
140
- if not DEFAULT_CONFIG_PATH.exists():
140
+ config_path = resolve_cli_config_path()
141
+ if not config_path.exists():
141
142
  return DEFAULT_MARKDOWN_THEME
142
- with DEFAULT_CONFIG_PATH.open("rb") as f:
143
+ with config_path.open("rb") as f:
143
144
  data = yaml.safe_load(f)
144
145
  except (yaml.YAMLError, PermissionError, OSError) as exc:
145
146
  logger.warning("Could not read config for markdown theme preference: %s", exc)
@@ -17,8 +17,42 @@ from soothe_sdk.paths import SOOTHE_HOME
17
17
 
18
18
  logger = logging.getLogger(__name__)
19
19
 
20
- # Default config path for Soothe
21
- DEFAULT_CONFIG_PATH = Path(SOOTHE_HOME) / "config" / "config.yml"
20
+ # CLI / TUI client preferences (themes, update prefs, skills dirs).
21
+ # Not the daemon agent config (nano.yml / soothe.yml).
22
+ _DEFAULT_CLI_CONFIG_PATH = Path(SOOTHE_HOME) / "config" / "cli.yml"
23
+ _LEGACY_CLI_CONFIG_PATH = Path(SOOTHE_HOME) / "config" / "config.yml"
24
+
25
+
26
+ def resolve_cli_config_path() -> Path:
27
+ """Return the CLI prefs path, migrating legacy ``config.yml`` once if needed.
28
+
29
+ Returns:
30
+ Path to ``~/.soothe/config/cli.yml`` (created/migrated lazily).
31
+ """
32
+ if _DEFAULT_CLI_CONFIG_PATH.exists():
33
+ return _DEFAULT_CLI_CONFIG_PATH
34
+ if _LEGACY_CLI_CONFIG_PATH.exists():
35
+ try:
36
+ _DEFAULT_CLI_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
37
+ _LEGACY_CLI_CONFIG_PATH.rename(_DEFAULT_CLI_CONFIG_PATH)
38
+ logger.info(
39
+ "Migrated CLI prefs from %s to %s",
40
+ _LEGACY_CLI_CONFIG_PATH,
41
+ _DEFAULT_CLI_CONFIG_PATH,
42
+ )
43
+ except OSError as exc:
44
+ logger.warning(
45
+ "Could not migrate legacy CLI prefs %s → %s: %s; using legacy path",
46
+ _LEGACY_CLI_CONFIG_PATH,
47
+ _DEFAULT_CLI_CONFIG_PATH,
48
+ exc,
49
+ )
50
+ return _LEGACY_CLI_CONFIG_PATH
51
+ return _DEFAULT_CLI_CONFIG_PATH
52
+
53
+
54
+ # Public path constant (prefer ``resolve_cli_config_path()`` when reading/writing).
55
+ DEFAULT_CONFIG_PATH = _DEFAULT_CLI_CONFIG_PATH
22
56
 
23
57
  # Environment variable prefix (Soothe uses SOOTHE_ instead of DEEPAGENTS_)
24
58
  _ENV_PREFIX = "SOOTHE_"
@@ -518,7 +552,7 @@ def get_available_models() -> list[ModelProfileEntry]:
518
552
  p_name,
519
553
  "",
520
554
  display_name=f"{p_name} ({provider_type})",
521
- description="Configure models: list under this provider in config.yml",
555
+ description="Configure models: list under this provider in nano.yml",
522
556
  )
523
557
  )
524
558
  else:
@@ -535,7 +569,7 @@ def get_available_models() -> list[ModelProfileEntry]:
535
569
  p_name,
536
570
  "",
537
571
  display_name=f"{p_name} ({provider_type})",
538
- description="Configure models: list under this provider in config.yml",
572
+ description="Configure models: list under this provider in nano.yml",
539
573
  )
540
574
  )
541
575
  return out
@@ -12,7 +12,7 @@ Code that needs custom CSS variable values should call
12
12
  `get_css_variable_defaults(dark=...)`. For the full semantic color palette, look
13
13
  up the `ThemeColors` instance via `ThemeEntry.REGISTRY`.
14
14
 
15
- Users can define custom themes in `~/SOOTHE_HOME/config/config.yml` under
15
+ Users can define custom themes in `~/SOOTHE_HOME/config/cli.yml` under
16
16
  `[themes.<name>]` sections. Each new theme section must include `label` (str);
17
17
  `dark` (bool) defaults to `False` if omitted (set to `True` for dark themes).
18
18
  Color fields are optional and fall back to the built-in dark/light palette based
@@ -29,7 +29,7 @@ from pathlib import Path
29
29
  from types import MappingProxyType
30
30
  from typing import TYPE_CHECKING, Any, ClassVar
31
31
 
32
- from soothe_sdk.paths import SOOTHE_HOME
32
+ from soothe_cli.tui.model_config import resolve_cli_config_path
33
33
 
34
34
  if TYPE_CHECKING:
35
35
  from collections.abc import Mapping
@@ -585,7 +585,7 @@ def _load_user_themes(
585
585
  *,
586
586
  config_path: Path | None = None,
587
587
  ) -> None:
588
- """Load user-defined themes from `config.yml` into `builtins` (mutated).
588
+ """Load user-defined themes from `cli.yml` into `builtins` (mutated).
589
589
 
590
590
  **New themes** — each `[themes.<name>]` section (where `<name>` is not a
591
591
  built-in) must have:
@@ -606,7 +606,7 @@ def _load_user_themes(
606
606
  Invalid themes (bad hex, missing required keys) are logged as warnings
607
607
  and skipped — they never crash startup.
608
608
 
609
- Example `config.yml` snippet:
609
+ Example `cli.yml` snippet:
610
610
 
611
611
  ```yaml
612
612
  # New custom theme
@@ -628,7 +628,7 @@ def _load_user_themes(
628
628
  """
629
629
  if config_path is None:
630
630
  try:
631
- config_path = Path(SOOTHE_HOME) / "config" / "config.yml"
631
+ config_path = resolve_cli_config_path()
632
632
  except RuntimeError:
633
633
  logger.debug("Cannot determine home directory; skipping user theme loading")
634
634
  return
@@ -778,7 +778,7 @@ DEFAULT_THEME = "textual-dark"
778
778
  def reload_registry() -> MappingProxyType[str, ThemeEntry]:
779
779
  """Rebuild the theme registry from disk and update `ThemeEntry.REGISTRY`.
780
780
 
781
- Re-reads `~/SOOTHE_HOME/config/config.yml` for user-defined themes so that
781
+ Re-reads `~/SOOTHE_HOME/config/cli.yml` for user-defined themes so that
782
782
  `/reload` can pick up config changes without restarting the app.
783
783
 
784
784
  Returns:
@@ -24,6 +24,7 @@ from packaging.version import InvalidVersion, Version
24
24
  from soothe_sdk.paths import SOOTHE_HOME
25
25
 
26
26
  from soothe_cli.tui._version import PYPI_URL, USER_AGENT, __version__
27
+ from soothe_cli.tui.model_config import resolve_cli_config_path
27
28
 
28
29
  logger = logging.getLogger(__name__)
29
30
 
@@ -321,7 +322,7 @@ def is_update_check_enabled() -> bool:
321
322
  Disabled when `SOOTHE_CLI_NO_UPDATE_CHECK` or legacy `SOOTHE_NO_UPDATE_CHECK`
322
323
  is set. When `SOOTHE_CLI_UPDATE_CHECK` is ``1``/``true``/``yes``, checks are
323
324
  enabled (including when ``[update].check: false`` would otherwise turn them
324
- off). Otherwise, respects ``[update].check`` in ``config.yml`` when
325
+ off). Otherwise, respects ``[update].check`` in ``cli.yml`` when
325
326
  present; defaults to on. Use ``/update`` to check manually any time.
326
327
  """
327
328
  from soothe_cli.tui._env_vars import NO_UPDATE_CHECK, UPDATE_CHECK
@@ -363,7 +364,7 @@ def is_auto_update_enabled() -> bool:
363
364
 
364
365
  Otherwise, ``SOOTHE_CLI_AUTO_UPDATE`` (or legacy ``SOOTHE_AUTO_UPDATE``)
365
366
  forces on or off when set. When unset, ``[update].auto_update`` in
366
- ``config.yml`` is used if present; defaults to on.
367
+ ``cli.yml`` is used if present; defaults to on.
367
368
  """
368
369
  from soothe_cli.tui.config import _is_editable_install
369
370
 
@@ -379,7 +380,7 @@ def is_auto_update_enabled() -> bool:
379
380
 
380
381
 
381
382
  def set_auto_update(enabled: bool) -> None:
382
- """Persist the auto-update preference to `config.yml`.
383
+ """Persist the auto-update preference to `cli.yml`.
383
384
 
384
385
  Writes `[update].auto_update` so the setting survives across sessions.
385
386
 
@@ -391,7 +392,7 @@ def set_auto_update(enabled: bool) -> None:
391
392
 
392
393
  import yaml
393
394
 
394
- config_path = Path(SOOTHE_HOME) / "config" / "config.yml"
395
+ config_path = resolve_cli_config_path()
395
396
  config_path.parent.mkdir(parents=True, exist_ok=True)
396
397
 
397
398
  if config_path.exists():
@@ -416,7 +417,7 @@ def set_auto_update(enabled: bool) -> None:
416
417
 
417
418
 
418
419
  def _read_update_config() -> dict[str, bool]:
419
- """Read `[update]` section from `config.yml`.
420
+ """Read `[update]` section from `cli.yml`.
420
421
 
421
422
  Returns:
422
423
  A dict of boolean config values, empty on missing/unreadable file.
@@ -424,7 +425,7 @@ def _read_update_config() -> dict[str, bool]:
424
425
  import yaml
425
426
 
426
427
  try:
427
- config_path = Path(SOOTHE_HOME) / "config" / "config.yml"
428
+ config_path = resolve_cli_config_path()
428
429
  if not config_path.exists():
429
430
  return {}
430
431
  with config_path.open("r") as f:
@@ -227,7 +227,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
227
227
  current_provider: The provider of the current model.
228
228
  cli_profile_override: Extra profile fields from `--profile-override`.
229
229
 
230
- Merged on top of upstream + config.yml profiles so that CLI
230
+ Merged on top of upstream + nano.yml profiles so that CLI
231
231
  overrides appear with `*` markers in the detail footer.
232
232
  preloaded: When set, skip local config discovery and use this
233
233
  ``(models, default_spec, profiles)`` tuple (e.g. from daemon ``models_list``).
@@ -386,7 +386,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
386
386
  self._loaded = True
387
387
  if self.is_running:
388
388
  self.notify(
389
- "Could not load model list. Check provider packages and config.yml.",
389
+ "Could not load model list. Check provider packages and nano.yml.",
390
390
  severity="error",
391
391
  timeout=10,
392
392
  markup=False,
@@ -31,7 +31,7 @@ class NotificationSettingsScreen(ModalScreen[None]):
31
31
  """Modal dialog for managing startup warning preferences.
32
32
 
33
33
  Each checkbox maps to a key in `[warnings].suppress` in
34
- `~/SOOTHE_HOME/config/config.yml`. Toggling a checkbox immediately
34
+ `~/SOOTHE_HOME/config/cli.yml`. Toggling a checkbox immediately
35
35
  persists the change.
36
36
  """
37
37
 
@@ -114,7 +114,7 @@ class NotificationSettingsScreen(ModalScreen[None]):
114
114
  container.styles.border = ("ascii", colors.success)
115
115
 
116
116
  def on_checkbox_changed(self, event: Checkbox.Changed) -> None:
117
- """Persist warning suppression toggle to config.yml on change."""
117
+ """Persist warning suppression toggle to cli.yml on change."""
118
118
  event.stop()
119
119
  checkbox_id = event.checkbox.id
120
120
  if not checkbox_id or not checkbox_id.startswith("ns-"):
@@ -142,7 +142,7 @@ class NotificationSettingsScreen(ModalScreen[None]):
142
142
  ok = False
143
143
  if not ok:
144
144
  self.app.notify(
145
- "Could not save notification preference. Check file permissions for ~/SOOTHE_HOME/config/config.yml.",
145
+ "Could not save notification preference. Check file permissions for ~/SOOTHE_HOME/config/cli.yml.",
146
146
  severity="warning",
147
147
  timeout=6,
148
148
  markup=False,
File without changes
File without changes