teddy-cli 0.1.17.dev1303__tar.gz → 0.1.17.dev1306__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 (162) hide show
  1. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/PKG-INFO +1 -1
  2. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/pyproject.toml +1 -1
  3. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/session_cli_handlers.py +5 -2
  4. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/context_service.py +3 -5
  5. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/markdown_report_formatter.py +2 -2
  6. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/parser_reporting.py +9 -8
  7. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_lifecycle_manager.py +2 -3
  8. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/templates/execution_report.md.j2 +9 -27
  9. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/edit.py +6 -7
  10. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/markdown.py +54 -0
  11. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/.gitignore +0 -0
  12. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/LICENSE +0 -0
  13. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/README.md +0 -0
  14. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/__init__.py +0 -0
  15. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/__main__.py +0 -0
  16. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/__init__.py +0 -0
  17. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/__init__.py +0 -0
  18. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/cli_formatter.py +0 -0
  19. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/cli_helpers.py +0 -0
  20. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer.py +0 -0
  21. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_app.py +0 -0
  22. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_editor.py +0 -0
  23. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_execution.py +0 -0
  24. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_helpers.py +0 -0
  25. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_logic.py +0 -0
  26. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_previews.py +0 -0
  27. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/inbound/textual_plan_reviewer_widgets.py +0 -0
  28. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/__init__.py +0 -0
  29. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/console_interactor.py +0 -0
  30. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/console_interactor_ask_loop.py +0 -0
  31. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/console_interactor_helpers.py +0 -0
  32. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/console_tooling.py +0 -0
  33. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/filesystem_helpers.py +0 -0
  34. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/litellm_adapter.py +0 -0
  35. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/local_file_system_adapter.py +0 -0
  36. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/local_repo_tree_generator.py +0 -0
  37. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/openrouter_hydrator.py +0 -0
  38. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/shell_adapter.py +0 -0
  39. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/shell_command_builder.py +0 -0
  40. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/suppressed_logging.py +0 -0
  41. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/system_environment_adapter.py +0 -0
  42. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/system_environment_inspector.py +0 -0
  43. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/system_time_adapter.py +0 -0
  44. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/terminal_quit_key_listener.py +0 -0
  45. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/web_scraper_adapter.py +0 -0
  46. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/web_searcher_adapter.py +0 -0
  47. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/adapters/outbound/yaml_config_adapter.py +0 -0
  48. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/container.py +0 -0
  49. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/__init__.py +0 -0
  50. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/__init__.py +0 -0
  51. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/__init__.py +0 -0
  52. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/action_ports.py +0 -0
  53. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/change_set.py +0 -0
  54. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/drift_report.py +0 -0
  55. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/exceptions.py +0 -0
  56. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/execution_report.py +0 -0
  57. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/orchestrator_ports.py +0 -0
  58. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/plan.py +0 -0
  59. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/planning_ports.py +0 -0
  60. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/project_context.py +0 -0
  61. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/report_assembly_data.py +0 -0
  62. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/session.py +0 -0
  63. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/shell_output.py +0 -0
  64. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/domain/models/web_search_results.py +0 -0
  65. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/__init__.py +0 -0
  66. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/__init__.py +0 -0
  67. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/edit_simulator.py +0 -0
  68. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/get_context_use_case.py +0 -0
  69. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/init.py +0 -0
  70. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/plan_parser.py +0 -0
  71. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/plan_reviewer.py +0 -0
  72. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/plan_validator.py +0 -0
  73. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/planning_use_case.py +0 -0
  74. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/inbound/run_plan_use_case.py +0 -0
  75. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/__init__.py +0 -0
  76. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/config_service.py +0 -0
  77. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/environment_inspector.py +0 -0
  78. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/execution_report_assembler.py +0 -0
  79. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/file_system_manager.py +0 -0
  80. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/llm_client.py +0 -0
  81. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/markdown_report_formatter.py +0 -0
  82. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/prompt_manager.py +0 -0
  83. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/quit_key_listener.py +0 -0
  84. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/repo_tree_generator.py +0 -0
  85. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/session_loop_guard.py +0 -0
  86. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/session_manager.py +0 -0
  87. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/session_repository.py +0 -0
  88. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/shell_executor.py +0 -0
  89. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/system_environment.py +0 -0
  90. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/time_service.py +0 -0
  91. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/user_interactor.py +0 -0
  92. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/web_scraper.py +0 -0
  93. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/ports/outbound/web_searcher.py +0 -0
  94. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/__init__.py +0 -0
  95. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/action_changeset_builder.py +0 -0
  96. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/action_diff_manager.py +0 -0
  97. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/action_dispatcher.py +0 -0
  98. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/action_executor.py +0 -0
  99. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/action_factory.py +0 -0
  100. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/action_parser_complex.py +0 -0
  101. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/action_parser_strategies.py +0 -0
  102. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/edit_simulator.py +0 -0
  103. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/execution_orchestrator.py +0 -0
  104. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/execution_report_assembler.py +0 -0
  105. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/init_service.py +0 -0
  106. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/markdown_plan_parser.py +0 -0
  107. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/parser_infrastructure.py +0 -0
  108. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/parser_metadata.py +0 -0
  109. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/plan_validator.py +0 -0
  110. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/planning_service.py +0 -0
  111. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/prompt_manager.py +0 -0
  112. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_loop_guard.py +0 -0
  113. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_orchestrator.py +0 -0
  114. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_planner.py +0 -0
  115. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_pruning_service.py +0 -0
  116. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_replanner.py +0 -0
  117. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_repository.py +0 -0
  118. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/session_service.py +0 -0
  119. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/update_checker.py +0 -0
  120. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/__init__.py +0 -0
  121. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/edit_matcher.py +0 -0
  122. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/edit_matcher_heuristics.py +0 -0
  123. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/execute.py +0 -0
  124. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/filesystem.py +0 -0
  125. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/helpers.py +0 -0
  126. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/services/validation_rules/message.py +0 -0
  127. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/__init__.py +0 -0
  128. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/diff.py +0 -0
  129. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/interrupt_guard.py +0 -0
  130. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/io.py +0 -0
  131. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/paths.py +0 -0
  132. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/serialization.py +0 -0
  133. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/session_notices.py +0 -0
  134. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/stdin_ownership.py +0 -0
  135. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/string.py +0 -0
  136. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/core/utils/terminal.py +0 -0
  137. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/prompts.py +0 -0
  138. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/registries/__init__.py +0 -0
  139. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/registries/infrastructure.py +0 -0
  140. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/registries/reviewer.py +0 -0
  141. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/registries/validators.py +0 -0
  142. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/MRP.md +0 -0
  143. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/__init__.py +0 -0
  144. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/__init__.py +0 -0
  145. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/config.yaml +0 -0
  146. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/init.context +0 -0
  147. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/prompts/architect.md +0 -0
  148. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/prompts/assistant.md +0 -0
  149. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/prompts/debugger.md +0 -0
  150. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/prompts/developer.md +0 -0
  151. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/prompts/pathfinder.md +0 -0
  152. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/config/prompts/prototyper.md +0 -0
  153. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/ARCHITECTURE.md +0 -0
  154. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/PROJECT.md +0 -0
  155. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/case-file.md +0 -0
  156. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/ci.md +0 -0
  157. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/component-design.md +0 -0
  158. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/makefile.md +0 -0
  159. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/milestone.md +0 -0
  160. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/pre-commit.md +0 -0
  161. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/src/teddy_executor/resources/templates/specification-document.md +0 -0
  162. {teddy_cli-0.1.17.dev1303 → teddy_cli-0.1.17.dev1306}/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.dev1303
3
+ Version: 0.1.17.dev1306
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.dev1303"
3
+ version = "0.1.17.dev1306"
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 = [
@@ -1166,8 +1166,11 @@ def handle_resume_session( # noqa: PLR0913
1166
1166
  container, session_name, model=model, api_key=api_key, agent=agent
1167
1167
  )
1168
1168
 
1169
- # 4. Display session path (below the Agent/Model identity block)
1170
- session_relative_path = str(Path(".teddy") / "sessions" / session_name)
1169
+ # 4. Display session path (below the Agent/Model identity block).
1170
+ # `.as_posix()` keeps the banner separator-identical on every OS
1171
+ # (Windows would otherwise emit backslashes) and matches the POSIX
1172
+ # f-string that `create_session` returns for the `start` banner.
1173
+ session_relative_path = (Path(".teddy") / "sessions" / session_name).as_posix()
1171
1174
  typer.echo(f"Resuming session: {session_relative_path}")
1172
1175
 
1173
1176
  # 5. Agent switch: if -a/--agent provided, update session agent permanently
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  from typing import Dict, List, Optional, Sequence
5
5
  from teddy_executor.core.domain.models import ProjectContext, ContextItem
6
6
  from teddy_executor.core.utils.markdown import (
7
- get_fence_for_content,
7
+ embed_in_fence,
8
8
  get_language_from_path,
9
9
  is_session_file_path,
10
10
  get_session_history_display_name,
@@ -396,8 +396,7 @@ class ContextService(IGetContextUseCase):
396
396
  content = file_contents.get(path)
397
397
  if content is not None:
398
398
  lang = get_language_from_path(path)
399
- fence = get_fence_for_content(content)
400
- parts.append(f"{fence}{lang}\n{content}\n{fence}")
399
+ parts.append(embed_in_fence(content, lang))
401
400
  else:
402
401
  parts.append("```\n--- FILE NOT FOUND ---\n```")
403
402
  return parts
@@ -471,7 +470,6 @@ class ContextService(IGetContextUseCase):
471
470
  content = file_contents.get(path) or ""
472
471
  content_str = content.strip()
473
472
  lang = get_language_from_path(path)
474
- fence = get_fence_for_content(content_str)
475
473
  parts.append(f"\n### {disp_name}")
476
- parts.append(f"{fence}{lang}\n{content_str}\n{fence}")
474
+ parts.append(embed_in_fence(content_str, lang))
477
475
  return parts
@@ -7,7 +7,7 @@ from teddy_executor.core.ports.outbound.markdown_report_formatter import (
7
7
  IMarkdownReportFormatter,
8
8
  )
9
9
  from teddy_executor.core.utils.markdown import (
10
- get_fence_for_content,
10
+ embed_in_fence,
11
11
  get_language_from_path,
12
12
  )
13
13
 
@@ -37,7 +37,7 @@ class MarkdownReportFormatter(IMarkdownReportFormatter):
37
37
  autoescape=False, # nosec B701
38
38
  )
39
39
  env.filters["basename"] = os.path.basename
40
- env.filters["fence"] = get_fence_for_content
40
+ env.filters["embed_fence"] = embed_in_fence
41
41
  env.filters["language_from_path"] = get_language_from_path
42
42
 
43
43
  MarkdownReportFormatter._cached_env = env
@@ -10,7 +10,7 @@ from teddy_executor.core.services.parser_infrastructure import (
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from mistletoe.block_token import Document
13
- from teddy_executor.core.utils.markdown import get_fence_for_content
13
+ from teddy_executor.core.utils.markdown import embed_in_fence
14
14
 
15
15
  # Maximum length for AST node previews in error reports
16
16
  MAX_PREVIEW_LENGTH = 60
@@ -48,9 +48,10 @@ def _format_expected_structure() -> str:
48
48
  "[004] Heading (Level 2: Action Plan) —or— Heading (Level 2: Message)",
49
49
  "[005...] (If Action Plan) Heading (Level 3: Action Type) and (Action-specific AST nodes)",
50
50
  ]
51
- content = "\n".join(lines) + "\n"
52
- fence = get_fence_for_content(content)
53
- return f"### Expected Response Structure (MRP) \n{fence}text\n{content}{fence}\n"
51
+ content = "\n".join(lines)
52
+ return (
53
+ f"### Expected Response Structure (MRP) \n{embed_in_fence(content, 'text')}\n"
54
+ )
54
55
 
55
56
 
56
57
  def format_node_name(node: Any) -> str:
@@ -137,9 +138,9 @@ def format_hybrid_ast_view(
137
138
  error_ids = {id(e.offending_node) for e in errors if e.offending_node}
138
139
  error_map = {id(e.offending_node): e.message for e in errors if e.offending_node}
139
140
  ast_text = _render_ast_view(doc, error_ids, error_map)
141
+ body = ast_text.rstrip("\n")
140
142
 
141
- fence = get_fence_for_content(ast_text)
142
- return f"### Plan AST with Highlighted Failures\n{fence}text\n{ast_text}{fence}\n"
143
+ return f"### Plan AST with Highlighted Failures\n{embed_in_fence(body, 'text')}\n"
143
144
 
144
145
 
145
146
  def get_action_type_from_node(plan: Plan, offending_node: Any) -> str:
@@ -270,8 +271,8 @@ def format_structural_mismatch_msg(
270
271
 
271
272
  cutoff = _get_failure_cutoff_idx(children, mismatch_idx, offending_ids)
272
273
  ast_text = _render_ast_view(doc, error_ids_set, error_map, cutoff)
273
- fence = get_fence_for_content(ast_text)
274
- msg += f"{fence}text\n{ast_text}{fence}\n"
274
+ body = ast_text.rstrip("\n")
275
+ msg += f"{embed_in_fence(body, 'text')}\n"
275
276
 
276
277
  msg += "\n**Hint:** Parsing often fails due to improper Code Block Formatting.\n"
277
278
  return msg
@@ -17,7 +17,7 @@ from teddy_executor.core.ports.inbound.plan_parser import InvalidPlanError
17
17
  from teddy_executor.core.ports.inbound.run_plan_use_case import IRunPlanUseCase
18
18
  from teddy_executor.core.ports.outbound.session_manager import SessionState
19
19
  from teddy_executor.core.utils.io import Tee as _Tee
20
- from teddy_executor.core.utils.markdown import get_fence_for_content
20
+ from teddy_executor.core.utils.markdown import embed_in_fence
21
21
 
22
22
  logger = logging.getLogger(__name__)
23
23
 
@@ -241,8 +241,7 @@ class SessionLifecycleManager:
241
241
  f"Cannot append user request: report not found at {report_path}"
242
242
  )
243
243
  content = str(self._file_system_manager.read_file(report_path)).rstrip("\n")
244
- fence = get_fence_for_content(message)
245
- content += f"\n\n## User Request\n{fence}text\n{message}\n{fence}\n"
244
+ content += f"\n\n## User Request\n{embed_in_fence(message, 'text')}\n"
246
245
  self._file_system_manager.write_file(report_path, content)
247
246
 
248
247
  def _consume_awaiting_reply( # noqa: PLR0913
@@ -15,9 +15,7 @@
15
15
  {% else %}
16
16
  ### [{{ path }}]({% if not path.startswith('/') %}/{% endif %}{{ path }})
17
17
  {% endif %}
18
- {{ content | fence }}{{ path | language_from_path }}
19
- {{ content }}
20
- {{ content | fence }}
18
+ {{ content | embed_fence(path | language_from_path) }}
21
19
  {% endmacro %}
22
20
 
23
21
  {% macro render_action_summary(log) %}
@@ -63,36 +61,26 @@
63
61
  {% if log.action_type.upper() == 'MESSAGE' and log.details %}
64
62
  {% if log.details is mapping and log.details.get('content') %}
65
63
  - **User Reply:**
66
- {{ log.details.content | trim | fence }}
67
- {{ log.details.content | trim }}
68
- {{ log.details.content | trim | fence }}
64
+ {{ log.details.content | trim | embed_fence('') }}
69
65
  {% else %}
70
66
  - **User Reply:**
71
- {{ log.details | trim | fence }}
72
- {{ log.details | trim }}
73
- {{ log.details | trim | fence }}
67
+ {{ log.details | trim | embed_fence('') }}
74
68
  {% endif %}
75
69
 
76
70
  {% elif log.details and log.details is mapping -%}
77
71
  {% if log.details.get("stdout") -%}
78
72
  #### `stdout`
79
- {{ log.details.stdout | trim | fence }}text
80
- {{ log.details.stdout | trim }}
81
- {{ log.details.stdout | trim | fence }}
73
+ {{ log.details.stdout | trim | embed_fence('text') }}
82
74
 
83
75
  {% endif -%}
84
76
  {% if log.details.get("stderr") -%}
85
77
  #### `stderr`
86
- {{ log.details.stderr | trim | fence }}text
87
- {{ log.details.stderr | trim }}
88
- {{ log.details.stderr | trim | fence }}
78
+ {{ log.details.stderr | trim | embed_fence('text') }}
89
79
 
90
80
  {% endif -%}
91
81
  {% if log.details.get("diff") -%}
92
82
  #### `diff`
93
- {{ log.details.diff | trim | fence }}diff
94
- {{ log.details.diff | trim }}
95
- {{ log.details.diff | trim | fence }}
83
+ {{ log.details.diff | trim | embed_fence('diff') }}
96
84
 
97
85
  {% endif -%}
98
86
  {% endif %}
@@ -229,9 +217,7 @@
229
217
  {% if cmd %}
230
218
 
231
219
  - **Command:** {% if '\n' in cmd %}
232
- {{ '\n' }}{{ cmd | fence }}shell
233
- {{ cmd }}
234
- {{ cmd | fence }}
220
+ {{ '\n' }}{{ cmd | embed_fence('shell') }}
235
221
  {% else %}`{{ cmd }}`{% endif %}
236
222
  {% endif %}
237
223
 
@@ -280,9 +266,7 @@ _**Hint:** NOW you MUST use READ on the most promising results_
280
266
  {% endif %}
281
267
 
282
268
  {% if log in report_ns.inline_logs %}
283
- {{ log.details.content | trim | fence }}
284
- {{ log.details.content | trim }}
285
- {{ log.details.content | trim | fence }}
269
+ {{ log.details.content | trim | embed_fence('') }}
286
270
  {% endif %}
287
271
 
288
272
  {{ render_action_blocks(log) }}
@@ -299,7 +283,5 @@ _**Hint:** NOW you MUST use READ on the most promising results_
299
283
  {% if report.user_request %}
300
284
 
301
285
  ## User Request
302
- {{ report.user_request | fence }}text
303
- {{ report.user_request }}
304
- {{ report.user_request | fence }}
286
+ {{ report.user_request | embed_fence('text') }}
305
287
  {% endif %}
@@ -22,7 +22,7 @@ from teddy_executor.core.services.validation_rules.helpers import (
22
22
  resolve_similarity_threshold,
23
23
  validate_path_is_safe,
24
24
  )
25
- from teddy_executor.core.utils.markdown import get_fence_for_content
25
+ from teddy_executor.core.utils.markdown import embed_in_fence
26
26
 
27
27
 
28
28
  class EditActionValidator(BaseActionValidator):
@@ -137,7 +137,7 @@ def _validate_single_edit(
137
137
  effective_threshold = (
138
138
  threshold if threshold is not None else DEFAULT_SIMILARITY_THRESHOLD
139
139
  )
140
- fence = get_fence_for_content(find_block)
140
+ find_embed = embed_in_fence(find_block, "")
141
141
 
142
142
  if is_ambiguous and not match_all and score >= effective_threshold:
143
143
  errors.append(
@@ -146,7 +146,7 @@ def _validate_single_edit(
146
146
  f"The `FIND` block is ambiguous in: {file_path}\n"
147
147
  f"**Similarity Score:** {score:.2f}\n"
148
148
  f"**FIND Block:**\n"
149
- f"{fence}\n{find_block}\n{fence}\n"
149
+ f"{find_embed}\n"
150
150
  "**Hint:** Please provide a larger FIND block to uniquely identify the section, refactor the code to avoid duplication. Alternatively you can use `Match All: true` to change all occurrences in the file at once."
151
151
  ),
152
152
  file_path=str(file_path),
@@ -159,16 +159,15 @@ def _validate_single_edit(
159
159
  f"**Similarity Score:** {score:.2f}\n"
160
160
  f"**Similarity Threshold:** {effective_threshold:.2f}\n"
161
161
  f"**FIND Block:**\n"
162
- f"{fence}\n{find_block}\n{fence}\n"
162
+ f"{find_embed}\n"
163
163
  )
164
164
  if diff_text:
165
165
  # Prepend standard diff headers for high-clarity diagnostics
166
166
  # ndiff(find, actual) means '-' is Provided and '+' is Actual
167
167
  formatted_diff = f"--- Provided\n+++ Actual\n{diff_text}"
168
- diff_fence = get_fence_for_content(formatted_diff)
169
168
  error_msg += (
170
- f"**Closest Match Diff:**\n{diff_fence}diff\n"
171
- f"{formatted_diff}\n{diff_fence}\n"
169
+ f"**Closest Match Diff:**\n"
170
+ f"{embed_in_fence(formatted_diff, 'diff')}\n"
172
171
  )
173
172
 
174
173
  hint = _get_already_applied_hint(
@@ -85,6 +85,60 @@ def get_fence_for_content(content: str) -> str:
85
85
  return "`" * fence_length
86
86
 
87
87
 
88
+ # A Markdown code fence: up to 3 leading spaces, then a run of 3+ backticks or
89
+ # tildes, then an optional info string (opening) or trailing whitespace (closing).
90
+ _FENCE_RE = re.compile(r"^ {0,3}(`{3,}|~{3,})(.*)$")
91
+
92
+
93
+ def strip_trailing_open_fence(content: str) -> str:
94
+ """Remove a trailing, UNCLOSED opening code fence from ``content``.
95
+
96
+ Walks the fence structure: if the content ends INSIDE an open code block,
97
+ that dangling opening fence line is removed. Balanced content -- including a
98
+ legitimate nested fence (a 4-backtick fence wrapping a 3-backtick fence) --
99
+ is returned byte-for-byte unchanged.
100
+ """
101
+ lines = content.split("\n")
102
+ open_char: str | None = None
103
+ open_len = 0
104
+ open_index: int | None = None
105
+
106
+ for index, line in enumerate(lines):
107
+ match = _FENCE_RE.match(line)
108
+ if match is None:
109
+ continue
110
+ fence = match.group(1)
111
+ info = match.group(2)
112
+ if open_char is None:
113
+ # Opening fence (any run >= 3 starts a block).
114
+ open_char = fence[0]
115
+ open_len = len(fence)
116
+ open_index = index
117
+ elif fence[0] == open_char and len(fence) >= open_len and not info.strip():
118
+ # Closing fence: same char, run at least as long, no info string.
119
+ open_char = None
120
+ open_len = 0
121
+ open_index = None
122
+
123
+ if open_index is None:
124
+ return content
125
+ # The content ends inside an open block: strip the dangling opening fence.
126
+ del lines[open_index]
127
+ return "\n".join(lines)
128
+
129
+
130
+ def embed_in_fence(content: str, lang: str) -> str:
131
+ """Sanitize ``content``, then wrap it in a safe, dynamically-sized fence.
132
+
133
+ Strips a trailing UNCLOSED fence BEFORE deriving the wrapper fence, so a
134
+ degenerate run cannot amplify the wrapper. The wrapper fence is sized from
135
+ the sanitized content, so it can never collide with content fences.
136
+ """
137
+ sanitized = strip_trailing_open_fence(content)
138
+ fence = get_fence_for_content(sanitized)
139
+ return f"{fence}{lang}\n{sanitized}\n{fence}"
140
+
141
+
88
142
  def get_session_history_display_name(path: str) -> str | None:
89
143
  """
90
144
  Returns human-readable display name if it's a recognized session history file.