teddy-cli 0.1.17.dev1401__tar.gz → 0.1.17.dev1402__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 (165) hide show
  1. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/PKG-INFO +1 -1
  2. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/pyproject.toml +1 -1
  3. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/__main__.py +17 -2
  4. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/yaml_config_adapter.py +32 -3
  5. teddy_cli-0.1.17.dev1402/src/teddy_executor/core/domain/models/config_schema.py +356 -0
  6. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/.gitignore +0 -0
  7. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/LICENSE +0 -0
  8. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/README.md +0 -0
  9. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/__init__.py +0 -0
  10. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/__init__.py +0 -0
  11. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/__init__.py +0 -0
  12. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/cli_formatter.py +0 -0
  13. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/cli_helpers.py +0 -0
  14. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/session_cli_handlers.py +0 -0
  15. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer.py +0 -0
  16. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_app.py +0 -0
  17. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_editor.py +0 -0
  18. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_execution.py +0 -0
  19. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_helpers.py +0 -0
  20. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_logic.py +0 -0
  21. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_previews.py +0 -0
  22. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_widgets.py +0 -0
  23. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/__init__.py +0 -0
  24. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_interactor.py +0 -0
  25. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_interactor_ask_loop.py +0 -0
  26. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_interactor_helpers.py +0 -0
  27. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_tooling.py +0 -0
  28. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/filesystem_helpers.py +0 -0
  29. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/litellm_adapter.py +0 -0
  30. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/local_file_system_adapter.py +0 -0
  31. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/local_repo_tree_generator.py +0 -0
  32. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/openrouter_hydrator.py +0 -0
  33. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/shell_adapter.py +0 -0
  34. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/shell_command_builder.py +0 -0
  35. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/suppressed_logging.py +0 -0
  36. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/system_environment_adapter.py +0 -0
  37. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/system_environment_inspector.py +0 -0
  38. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/system_time_adapter.py +0 -0
  39. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/terminal_quit_key_listener.py +0 -0
  40. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/web_scraper_adapter.py +0 -0
  41. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/web_searcher_adapter.py +0 -0
  42. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/container.py +0 -0
  43. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/__init__.py +0 -0
  44. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/__init__.py +0 -0
  45. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/__init__.py +0 -0
  46. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/action_ports.py +0 -0
  47. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/change_set.py +0 -0
  48. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/drift_report.py +0 -0
  49. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/exceptions.py +0 -0
  50. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/execution_report.py +0 -0
  51. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/orchestrator_ports.py +0 -0
  52. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/plan.py +0 -0
  53. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/planning_ports.py +0 -0
  54. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/project_context.py +0 -0
  55. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/report_assembly_data.py +0 -0
  56. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/session.py +0 -0
  57. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/shell_output.py +0 -0
  58. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/web_search_results.py +0 -0
  59. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/__init__.py +0 -0
  60. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/__init__.py +0 -0
  61. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/edit_simulator.py +0 -0
  62. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/get_context_use_case.py +0 -0
  63. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/init.py +0 -0
  64. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/plan_parser.py +0 -0
  65. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/plan_reviewer.py +0 -0
  66. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/plan_validator.py +0 -0
  67. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/planning_use_case.py +0 -0
  68. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/run_plan_use_case.py +0 -0
  69. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/__init__.py +0 -0
  70. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/config_service.py +0 -0
  71. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/environment_inspector.py +0 -0
  72. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/execution_report_assembler.py +0 -0
  73. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/file_system_manager.py +0 -0
  74. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/llm_client.py +0 -0
  75. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/markdown_report_formatter.py +0 -0
  76. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/prompt_manager.py +0 -0
  77. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/quit_key_listener.py +0 -0
  78. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/repo_tree_generator.py +0 -0
  79. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/session_loop_guard.py +0 -0
  80. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/session_manager.py +0 -0
  81. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/session_repository.py +0 -0
  82. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/shell_executor.py +0 -0
  83. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/system_environment.py +0 -0
  84. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/time_service.py +0 -0
  85. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/user_interactor.py +0 -0
  86. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/web_scraper.py +0 -0
  87. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/web_searcher.py +0 -0
  88. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/__init__.py +0 -0
  89. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_changeset_builder.py +0 -0
  90. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_diff_manager.py +0 -0
  91. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_dispatcher.py +0 -0
  92. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_executor.py +0 -0
  93. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_factory.py +0 -0
  94. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_parser_complex.py +0 -0
  95. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_parser_strategies.py +0 -0
  96. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/context_service.py +0 -0
  97. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/edit_simulator.py +0 -0
  98. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/execution_orchestrator.py +0 -0
  99. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/execution_report_assembler.py +0 -0
  100. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/init_service.py +0 -0
  101. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/markdown_plan_parser.py +0 -0
  102. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/markdown_report_formatter.py +0 -0
  103. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/parser_infrastructure.py +0 -0
  104. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/parser_metadata.py +0 -0
  105. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/parser_reporting.py +0 -0
  106. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/plan_validator.py +0 -0
  107. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/planning_service.py +0 -0
  108. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/prompt_manager.py +0 -0
  109. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_lifecycle_manager.py +0 -0
  110. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_loop_guard.py +0 -0
  111. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_orchestrator.py +0 -0
  112. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_planner.py +0 -0
  113. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_pruning_service.py +0 -0
  114. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_replanner.py +0 -0
  115. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_repository.py +0 -0
  116. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_service.py +0 -0
  117. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/templates/execution_report.md.j2 +0 -0
  118. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/update_checker.py +0 -0
  119. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/__init__.py +0 -0
  120. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/edit.py +0 -0
  121. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/edit_matcher.py +0 -0
  122. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/edit_matcher_heuristics.py +0 -0
  123. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/execute.py +0 -0
  124. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/filesystem.py +0 -0
  125. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/helpers.py +0 -0
  126. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/message.py +0 -0
  127. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/__init__.py +0 -0
  128. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/diff.py +0 -0
  129. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/editor_names.py +0 -0
  130. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/interrupt_guard.py +0 -0
  131. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/interruptible_call.py +0 -0
  132. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/io.py +0 -0
  133. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/markdown.py +0 -0
  134. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/paths.py +0 -0
  135. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/serialization.py +0 -0
  136. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/session_notices.py +0 -0
  137. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/stdin_ownership.py +0 -0
  138. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/string.py +0 -0
  139. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/terminal.py +0 -0
  140. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/prompts.py +0 -0
  141. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/__init__.py +0 -0
  142. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/infrastructure.py +0 -0
  143. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/reviewer.py +0 -0
  144. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/validators.py +0 -0
  145. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/MRP.md +0 -0
  146. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/__init__.py +0 -0
  147. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/__init__.py +0 -0
  148. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/config.yaml +0 -0
  149. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/init.context +0 -0
  150. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/architect.md +0 -0
  151. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/assistant.md +0 -0
  152. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/debugger.md +0 -0
  153. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/developer.md +0 -0
  154. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/pathfinder.md +0 -0
  155. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/prototyper.md +0 -0
  156. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/ARCHITECTURE.md +0 -0
  157. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/PROJECT.md +0 -0
  158. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/case-file.md +0 -0
  159. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/ci.md +0 -0
  160. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/component-design.md +0 -0
  161. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/makefile.md +0 -0
  162. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/milestone.md +0 -0
  163. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/pre-commit.md +0 -0
  164. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/specification-document.md +0 -0
  165. {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/vertical-slice.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: teddy-cli
3
- Version: 0.1.17.dev1401
3
+ Version: 0.1.17.dev1402
4
4
  Summary: The local-first, test-driven agentic engineering harness. Because you should own the means of development.
5
5
  Author: Raphael Atteritano
6
6
  License: AGPL-3.0-only
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "teddy-cli"
3
- version = "0.1.17.dev1401"
3
+ version = "0.1.17.dev1402"
4
4
  description = "The local-first, test-driven agentic engineering harness. Because you should own the means of development."
5
5
  readme = "README.md"
6
6
  keywords = [
@@ -11,6 +11,7 @@ import typer
11
11
  from teddy_executor.core.domain.models import (
12
12
  ExecutionReport,
13
13
  )
14
+ from teddy_executor.core.domain.models.exceptions import ConfigurationError
14
15
  from teddy_executor.core.ports.outbound.config_service import IConfigService
15
16
  from teddy_executor.core.ports.outbound.system_environment import ISystemEnvironment
16
17
 
@@ -129,6 +130,20 @@ def _display_init_drift(container) -> None:
129
130
  _display_checks_footer(_display_drift_notification(container))
130
131
 
131
132
 
133
+ def _resolve_config_or_exit(container) -> IConfigService:
134
+ """Resolve the config service, failing fast on an invalid configuration.
135
+
136
+ A value that cannot be coerced to its declared type raises
137
+ ``ConfigurationError`` during adapter construction. Printing the message
138
+ and exiting keeps the failure visible instead of escaping as a traceback.
139
+ """
140
+ try:
141
+ return container.resolve(IConfigService)
142
+ except ConfigurationError as error:
143
+ typer.secho(f"Error: {error}", fg=typer.colors.RED, err=True)
144
+ raise typer.Exit(code=1) from error
145
+
146
+
132
147
  def _ensure_project_initialized(container, root_dir: str | None = None) -> None:
133
148
  """Lazily performs project anchoring and initialization.
134
149
 
@@ -246,7 +261,7 @@ def start( # noqa: PLR0913
246
261
 
247
262
  container = get_container()
248
263
  _ensure_project_initialized(container)
249
- config_service = container.resolve(IConfigService)
264
+ config_service = _resolve_config_or_exit(container)
250
265
 
251
266
  from teddy_executor.adapters.inbound.cli_helpers import normalize_context_values
252
267
 
@@ -538,7 +553,7 @@ def resume( # noqa: PLR0913
538
553
 
539
554
  container = get_container()
540
555
  _ensure_project_initialized(container)
541
- config_service = container.resolve(IConfigService)
556
+ config_service = _resolve_config_or_exit(container)
542
557
 
543
558
  interactive = not (_resolve_yolo(yolo, config_service) or pipeline)
544
559
  system_env = container.resolve(ISystemEnvironment)
@@ -5,6 +5,11 @@ from importlib import resources
5
5
  from typing import Any, Dict, Optional
6
6
  import yaml
7
7
  from dotenv import dotenv_values, set_key
8
+ from teddy_executor.core.domain.models.config_schema import (
9
+ construct_app_config,
10
+ is_declared_key,
11
+ read_declared_value,
12
+ )
8
13
  from teddy_executor.core.domain.models.exceptions import ConfigurationError
9
14
  from teddy_executor.core.ports.outbound.config_service import IConfigService
10
15
 
@@ -21,6 +26,10 @@ _LEGACY_EXECUTION_KEY_GROUPS = {
21
26
  "similarity_threshold": "edit",
22
27
  }
23
28
 
29
+ # ``llm.*`` keys pass straight through to LiteLLM and stay on the live walk,
30
+ # because a mid-run ``.env`` write must remain visible on the same adapter.
31
+ _PASSTHROUGH_KEY_PREFIX = "llm."
32
+
24
33
 
25
34
  def _strict_load(text: str, source_path: str) -> Any:
26
35
  """Parse ``text`` and reject a repeated mapping key at any depth."""
@@ -83,6 +92,15 @@ class YamlConfigAdapter(IConfigService):
83
92
  else:
84
93
  self._config_path = config_path
85
94
  self._config: Dict[str, Any] = self._load_layered_config()
95
+ self._refresh_typed_view()
96
+
97
+ def _refresh_typed_view(self) -> None:
98
+ """Rebuild the typed view from the current merged cache.
99
+
100
+ The view is a frozen snapshot, so it must be reconstructed whenever
101
+ the merged cache changes, or a read would return a stale value.
102
+ """
103
+ self.app_config = construct_app_config(self._maybe_interpolate(self._config))
86
104
 
87
105
  def _load_layered_config(self) -> Dict[str, Any]:
88
106
  """Loads the baseline config and merges it with the user config."""
@@ -167,15 +185,24 @@ class YamlConfigAdapter(IConfigService):
167
185
  """
168
186
  Retrieves a configuration value by its key from the loaded YAML.
169
187
  Supports nested keys using dot notation (e.g., 'outer.inner').
188
+
189
+ A schema-declared key resolves through the typed view, so its value is
190
+ coerced to the declared type. Every other key resolves through the live
191
+ dict walk, which covers undeclared keys and the ``llm.*`` passthrough.
170
192
  """
171
193
  if not key:
172
194
  return default
173
195
 
174
- # 1. Try exact match first (highest priority: top-level user overrides)
196
+ # 1. Declared keys resolve through the typed view. Passthrough keys are
197
+ # excluded because a construction-time snapshot would go stale.
198
+ if not key.startswith(_PASSTHROUGH_KEY_PREFIX) and is_declared_key(key):
199
+ return read_declared_value(self.app_config, key)
200
+
201
+ # 2. Try exact match first (highest priority: top-level user overrides)
175
202
  if key in self._config:
176
203
  return self._maybe_interpolate(self._config[key])
177
204
 
178
- # 2. Try nested resolution (standard hierarchical structure)
205
+ # 3. Try nested resolution (standard hierarchical structure)
179
206
  parts = key.split(".")
180
207
  result = self._resolve_nested(parts)
181
208
 
@@ -302,10 +329,12 @@ class YamlConfigAdapter(IConfigService):
302
329
  f.write(text)
303
330
 
304
331
  # 4. Rebuild the merged cache from disk so a subsequent get_setting()
305
- # on THIS adapter resolves exactly what a fresh adapter resolves.
332
+ # on THIS adapter resolves exactly what a fresh adapter resolves,
333
+ # then refresh the typed view so app_config reflects the write.
306
334
  merged = self._load_layered_config()
307
335
  self._config.clear()
308
336
  self._config.update(merged)
337
+ self._refresh_typed_view()
309
338
 
310
339
  def _scalar_repr(self, value: Any) -> str:
311
340
  """Render a scalar value as YAML text with no document-end marker."""
@@ -0,0 +1,356 @@
1
+ """Typed configuration schema.
2
+
3
+ The schema declares the type and canonical default of every fixed
4
+ configuration key. It is an internal layer: the end-user ``config.yaml`` shape
5
+ is unchanged. Construction resolves each declared key with exact-flat-first
6
+ then nested precedence, coerces a safe string to its declared type, and falls
7
+ back to the schema default when a value is absent.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import logging
13
+ from collections.abc import Mapping
14
+ from dataclasses import dataclass, field
15
+ from typing import Any
16
+
17
+ from teddy_executor.core.domain.models.exceptions import ConfigurationError
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class ExecuteConfig:
24
+ default_timeout_seconds: float = 60.0
25
+ max_output_lines: int = 100
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class EditConfig:
30
+ similarity_threshold: float = 0.95
31
+
32
+
33
+ @dataclass(frozen=True)
34
+ class WorkspaceConfig:
35
+ init: bool = True
36
+ pre_commit: bool = True
37
+ pull: bool = True
38
+
39
+
40
+ @dataclass(frozen=True)
41
+ class ReadConfig:
42
+ max_lines: int = 1000
43
+
44
+
45
+ @dataclass(frozen=True)
46
+ class ContextConfig:
47
+ max_tree_depth: int = 4
48
+
49
+
50
+ @dataclass(frozen=True)
51
+ class ResearchConfig:
52
+ max_results: int = 5
53
+
54
+
55
+ @dataclass(frozen=True)
56
+ class ChecksConfig:
57
+ prompts: bool = True
58
+ templates: bool = True
59
+ update: bool = True
60
+
61
+
62
+ @dataclass(frozen=True)
63
+ class AutoPruningConfig:
64
+ enabled: bool = True
65
+ turn_context_threshold: int = 50000
66
+ prune_failure_history: bool = True
67
+ prune_validation_failures: bool = True
68
+ preserve_message_turns: bool = True
69
+ max_turns_retention: int = 10
70
+
71
+
72
+ @dataclass(frozen=True)
73
+ class GuardrailsConfig:
74
+ enabled: bool = True
75
+ max_turns: int = 150
76
+ max_session_cost: float = 5.0
77
+ message_reset: bool = True
78
+
79
+
80
+ @dataclass(frozen=True)
81
+ class AppConfig:
82
+ execute: ExecuteConfig = field(default_factory=ExecuteConfig)
83
+ edit: EditConfig = field(default_factory=EditConfig)
84
+ workspace: WorkspaceConfig = field(default_factory=WorkspaceConfig)
85
+ read: ReadConfig = field(default_factory=ReadConfig)
86
+ context: ContextConfig = field(default_factory=ContextConfig)
87
+ research: ResearchConfig = field(default_factory=ResearchConfig)
88
+ checks: ChecksConfig = field(default_factory=ChecksConfig)
89
+ auto_pruning: AutoPruningConfig = field(default_factory=AutoPruningConfig)
90
+ guardrails: GuardrailsConfig = field(default_factory=GuardrailsConfig)
91
+ editor: str = ""
92
+ yolo_default: bool = False
93
+
94
+
95
+ DEFAULT_APP_CONFIG = AppConfig()
96
+
97
+
98
+ def _lookup(merged: Mapping[str, Any], key: str) -> Any:
99
+ """Resolve ``key`` with exact-flat-first then nested precedence.
100
+
101
+ ``get_setting`` treats a top-level dotted key as a higher priority than the
102
+ nested path. The schema mirrors that order so typed access and string access
103
+ stay in parity.
104
+ """
105
+ if key in merged:
106
+ return merged[key]
107
+ current: Any = merged
108
+ for part in key.split("."):
109
+ if isinstance(current, Mapping) and part in current:
110
+ current = current[part]
111
+ else:
112
+ return None
113
+ return current
114
+
115
+
116
+ def _coerce_int(key: str, value: Any) -> int:
117
+ """Coerce ``value`` to an ``int`` or raise a named configuration error."""
118
+ expected = f"Configuration key '{key}' expected int, got {value!r}."
119
+ if isinstance(value, int) and not isinstance(value, bool):
120
+ return value
121
+ if isinstance(value, str):
122
+ try:
123
+ return int(value)
124
+ except ValueError:
125
+ raise ConfigurationError(expected) from None
126
+ raise ConfigurationError(expected)
127
+
128
+
129
+ def _coerce_float(key: str, value: Any) -> float:
130
+ """Coerce ``value`` to a ``float`` or raise a named configuration error."""
131
+ expected = f"Configuration key '{key}' expected float, got {value!r}."
132
+ if isinstance(value, (int, float)) and not isinstance(value, bool):
133
+ return float(value)
134
+ if isinstance(value, str):
135
+ try:
136
+ return float(value)
137
+ except ValueError:
138
+ raise ConfigurationError(expected) from None
139
+ raise ConfigurationError(expected)
140
+
141
+
142
+ _TRUE_TOKENS = frozenset({"true", "yes", "on"})
143
+ _FALSE_TOKENS = frozenset({"false", "no", "off"})
144
+
145
+
146
+ def _coerce_bool(key: str, value: Any) -> bool:
147
+ """Coerce ``value`` to a ``bool`` or raise a named configuration error.
148
+
149
+ Only real booleans and the documented ``true``/``false``, ``yes``/``no``,
150
+ and ``on``/``off`` spellings are accepted, case-insensitively.
151
+ """
152
+ expected = f"Configuration key '{key}' expected bool, got {value!r}."
153
+ if isinstance(value, bool):
154
+ return value
155
+ if isinstance(value, str):
156
+ token = value.strip().lower()
157
+ if token in _TRUE_TOKENS:
158
+ return True
159
+ if token in _FALSE_TOKENS:
160
+ return False
161
+ raise ConfigurationError(expected)
162
+
163
+
164
+ def _coerce_str(key: str, value: Any) -> str:
165
+ """Coerce ``value`` to a ``str`` or raise a named configuration error."""
166
+ if isinstance(value, str):
167
+ return value
168
+ raise ConfigurationError(f"Configuration key '{key}' expected str, got {value!r}.")
169
+
170
+
171
+ @dataclass(frozen=True)
172
+ class _FieldSpec:
173
+ """Declares one configuration key, its typed target, and its valid range.
174
+
175
+ ``group`` names the owning dataclass on ``AppConfig``. A ``None`` group
176
+ marks a top-level scalar key that lives directly on ``AppConfig``. The
177
+ ``minimum`` and ``maximum`` bounds are inclusive, and a ``None`` bound
178
+ leaves that side unbounded, so a spec without bounds accepts any coercible
179
+ value.
180
+ """
181
+
182
+ key: str
183
+ group: str | None
184
+ target: str
185
+ kind: type
186
+ minimum: float | None = None
187
+ maximum: float | None = None
188
+
189
+
190
+ _SCHEMA_FIELDS: tuple[_FieldSpec, ...] = (
191
+ _FieldSpec("editor", None, "editor", str),
192
+ _FieldSpec(
193
+ "execute.default_timeout_seconds",
194
+ "execute",
195
+ "default_timeout_seconds",
196
+ float,
197
+ ),
198
+ _FieldSpec(
199
+ "execute.max_output_lines", "execute", "max_output_lines", int, minimum=1
200
+ ),
201
+ _FieldSpec(
202
+ "edit.similarity_threshold",
203
+ "edit",
204
+ "similarity_threshold",
205
+ float,
206
+ minimum=0.0,
207
+ maximum=1.0,
208
+ ),
209
+ _FieldSpec("workspace.init", "workspace", "init", bool),
210
+ _FieldSpec("workspace.pre-commit", "workspace", "pre_commit", bool),
211
+ _FieldSpec("workspace.pull", "workspace", "pull", bool),
212
+ _FieldSpec("read.max_lines", "read", "max_lines", int, minimum=1),
213
+ _FieldSpec("context.max_tree_depth", "context", "max_tree_depth", int, minimum=0),
214
+ _FieldSpec("research.max_results", "research", "max_results", int, minimum=1),
215
+ _FieldSpec("checks.prompts", "checks", "prompts", bool),
216
+ _FieldSpec("checks.templates", "checks", "templates", bool),
217
+ _FieldSpec("checks.update", "checks", "update", bool),
218
+ _FieldSpec("auto_pruning.enabled", "auto_pruning", "enabled", bool),
219
+ _FieldSpec(
220
+ "auto_pruning.turn_context_threshold",
221
+ "auto_pruning",
222
+ "turn_context_threshold",
223
+ int,
224
+ ),
225
+ _FieldSpec(
226
+ "auto_pruning.prune_failure_history",
227
+ "auto_pruning",
228
+ "prune_failure_history",
229
+ bool,
230
+ ),
231
+ _FieldSpec(
232
+ "auto_pruning.prune_validation_failures",
233
+ "auto_pruning",
234
+ "prune_validation_failures",
235
+ bool,
236
+ ),
237
+ _FieldSpec(
238
+ "auto_pruning.preserve_message_turns",
239
+ "auto_pruning",
240
+ "preserve_message_turns",
241
+ bool,
242
+ ),
243
+ _FieldSpec(
244
+ "auto_pruning.max_turns_retention",
245
+ "auto_pruning",
246
+ "max_turns_retention",
247
+ int,
248
+ ),
249
+ _FieldSpec("guardrails.enabled", "guardrails", "enabled", bool),
250
+ _FieldSpec("guardrails.max_turns", "guardrails", "max_turns", int),
251
+ _FieldSpec("guardrails.max_session_cost", "guardrails", "max_session_cost", float),
252
+ _FieldSpec("guardrails.message_reset", "guardrails", "message_reset", bool),
253
+ _FieldSpec("yolo_default", None, "yolo_default", bool),
254
+ )
255
+
256
+ _DECLARED_KEY_TARGETS: dict[str, tuple[str | None, str]] = {
257
+ spec.key: (spec.group, spec.target) for spec in _SCHEMA_FIELDS
258
+ }
259
+
260
+ _KNOWN_TOP_LEVEL = frozenset(
261
+ {spec.group for spec in _SCHEMA_FIELDS if spec.group is not None}
262
+ | {spec.key for spec in _SCHEMA_FIELDS if spec.group is None}
263
+ | {"llm"}
264
+ )
265
+
266
+
267
+ def is_declared_key(key: str) -> bool:
268
+ """Report whether ``key`` is a schema-declared configuration key."""
269
+ return key in _DECLARED_KEY_TARGETS
270
+
271
+
272
+ def read_declared_value(config: AppConfig, key: str) -> Any:
273
+ """Read the typed value of a declared ``key`` from ``config``.
274
+
275
+ A declared value is always present, because construction fills every
276
+ undeclared or empty value with its schema default.
277
+ """
278
+ assert is_declared_key(key), f"key {key!r} is not declared in the schema"
279
+ group, target = _DECLARED_KEY_TARGETS[key]
280
+ if group is None:
281
+ return getattr(config, target)
282
+ return getattr(getattr(config, group), target)
283
+
284
+
285
+ def _coerce(spec: _FieldSpec, value: Any) -> Any:
286
+ """Coerce ``value`` to the declared type of ``spec``."""
287
+ if spec.kind is bool:
288
+ return _coerce_bool(spec.key, value)
289
+ if spec.kind is int:
290
+ return _coerce_int(spec.key, value)
291
+ if spec.kind is str:
292
+ return _coerce_str(spec.key, value)
293
+ return _coerce_float(spec.key, value)
294
+
295
+
296
+ def _validate_range(spec: _FieldSpec, value: Any) -> Any:
297
+ """Reject a value outside the declared inclusive bounds.
298
+
299
+ The error names the key, the expected bound, and the offending value, so a
300
+ user can correct the file from the message alone.
301
+ """
302
+ if spec.minimum is not None and value < spec.minimum:
303
+ raise ConfigurationError(
304
+ f"Configuration key '{spec.key}' expected a value of at least "
305
+ f"{spec.minimum}, got {value!r}."
306
+ )
307
+ if spec.maximum is not None and value > spec.maximum:
308
+ raise ConfigurationError(
309
+ f"Configuration key '{spec.key}' expected a value of at most "
310
+ f"{spec.maximum}, got {value!r}."
311
+ )
312
+ return value
313
+
314
+
315
+ def _log_unknown_keys(merged: Mapping[str, Any]) -> None:
316
+ """Record each undeclared top-level group at debug level."""
317
+ for key in merged:
318
+ if key not in _KNOWN_TOP_LEVEL:
319
+ logger.debug("Ignoring unknown configuration group %r", key)
320
+
321
+
322
+ def construct_app_config(merged: Mapping[str, Any]) -> AppConfig:
323
+ """Build the typed configuration view from the merged config mapping.
324
+
325
+ Each declared key resolves with exact-flat-first then nested precedence. A
326
+ declared value coerces to its declared type, and an absent or empty value
327
+ falls back to the schema default. An uncoercible value or a value outside
328
+ its declared range raises a ``ConfigurationError`` naming the key.
329
+ Undeclared top-level groups are ignored so future keys stay forward
330
+ compatible.
331
+ """
332
+ _log_unknown_keys(merged)
333
+ group_overrides: dict[str, dict[str, Any]] = {}
334
+ top_level_overrides: dict[str, Any] = {}
335
+ for spec in _SCHEMA_FIELDS:
336
+ raw = _lookup(merged, spec.key)
337
+ if raw is None or raw == "":
338
+ continue
339
+ coerced = _validate_range(spec, _coerce(spec, raw))
340
+ if spec.group is None:
341
+ top_level_overrides[spec.target] = coerced
342
+ else:
343
+ group_overrides.setdefault(spec.group, {})[spec.target] = coerced
344
+
345
+ return AppConfig(
346
+ execute=ExecuteConfig(**group_overrides.get("execute", {})),
347
+ edit=EditConfig(**group_overrides.get("edit", {})),
348
+ workspace=WorkspaceConfig(**group_overrides.get("workspace", {})),
349
+ read=ReadConfig(**group_overrides.get("read", {})),
350
+ context=ContextConfig(**group_overrides.get("context", {})),
351
+ research=ResearchConfig(**group_overrides.get("research", {})),
352
+ checks=ChecksConfig(**group_overrides.get("checks", {})),
353
+ auto_pruning=AutoPruningConfig(**group_overrides.get("auto_pruning", {})),
354
+ guardrails=GuardrailsConfig(**group_overrides.get("guardrails", {})),
355
+ **top_level_overrides,
356
+ )