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.
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/PKG-INFO +1 -1
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/pyproject.toml +1 -1
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/__main__.py +17 -2
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/yaml_config_adapter.py +32 -3
- teddy_cli-0.1.17.dev1402/src/teddy_executor/core/domain/models/config_schema.py +356 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/.gitignore +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/LICENSE +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/README.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/cli_formatter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/cli_helpers.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/session_cli_handlers.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_app.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_editor.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_execution.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_helpers.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_logic.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_previews.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_widgets.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_interactor.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_interactor_ask_loop.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_interactor_helpers.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/console_tooling.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/filesystem_helpers.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/litellm_adapter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/local_file_system_adapter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/local_repo_tree_generator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/openrouter_hydrator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/shell_adapter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/shell_command_builder.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/suppressed_logging.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/system_environment_adapter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/system_environment_inspector.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/system_time_adapter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/terminal_quit_key_listener.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/web_scraper_adapter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/outbound/web_searcher_adapter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/container.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/action_ports.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/change_set.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/drift_report.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/exceptions.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/execution_report.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/orchestrator_ports.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/plan.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/planning_ports.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/project_context.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/report_assembly_data.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/session.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/shell_output.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/web_search_results.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/edit_simulator.py +0 -0
- {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
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/init.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/plan_parser.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/plan_reviewer.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/plan_validator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/planning_use_case.py +0 -0
- {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
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/config_service.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/environment_inspector.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/execution_report_assembler.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/file_system_manager.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/llm_client.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/markdown_report_formatter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/prompt_manager.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/quit_key_listener.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/repo_tree_generator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/session_loop_guard.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/session_manager.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/session_repository.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/shell_executor.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/system_environment.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/time_service.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/user_interactor.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/web_scraper.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/outbound/web_searcher.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_changeset_builder.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_diff_manager.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_dispatcher.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_executor.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_factory.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_parser_complex.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/action_parser_strategies.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/context_service.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/edit_simulator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/execution_orchestrator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/execution_report_assembler.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/init_service.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/markdown_plan_parser.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/markdown_report_formatter.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/parser_infrastructure.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/parser_metadata.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/parser_reporting.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/plan_validator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/planning_service.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/prompt_manager.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_lifecycle_manager.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_loop_guard.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_orchestrator.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_planner.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_pruning_service.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_replanner.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_repository.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/session_service.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/templates/execution_report.md.j2 +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/update_checker.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/edit.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/edit_matcher.py +0 -0
- {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
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/execute.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/filesystem.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/helpers.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/validation_rules/message.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/diff.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/editor_names.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/interrupt_guard.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/interruptible_call.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/io.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/markdown.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/paths.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/serialization.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/session_notices.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/stdin_ownership.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/string.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/terminal.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/prompts.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/infrastructure.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/reviewer.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/validators.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/MRP.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/__init__.py +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/config.yaml +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/init.context +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/architect.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/assistant.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/debugger.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/developer.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/pathfinder.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/config/prompts/prototyper.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/ARCHITECTURE.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/PROJECT.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/case-file.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/ci.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/component-design.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/makefile.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/milestone.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/pre-commit.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/specification-document.md +0 -0
- {teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/vertical-slice.md +0 -0
|
@@ -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
|
|
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
|
|
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.
|
|
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
|
-
#
|
|
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
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/adapters/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/domain/models/plan.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/ports/inbound/init.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/editor_names.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/markdown.py
RENAMED
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/paths.py
RENAMED
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/serialization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/string.py
RENAMED
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/core/utils/terminal.py
RENAMED
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/reviewer.py
RENAMED
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/registries/validators.py
RENAMED
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{teddy_cli-0.1.17.dev1401 → teddy_cli-0.1.17.dev1402}/src/teddy_executor/resources/templates/ci.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|