teddy-cli 0.1.0__py3-none-any.whl
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.0.dist-info/LICENSE +677 -0
- teddy_cli-0.1.0.dist-info/METADATA +33 -0
- teddy_cli-0.1.0.dist-info/RECORD +143 -0
- teddy_cli-0.1.0.dist-info/WHEEL +4 -0
- teddy_cli-0.1.0.dist-info/entry_points.txt +3 -0
- teddy_executor/__init__.py +1 -0
- teddy_executor/__main__.py +335 -0
- teddy_executor/adapters/__init__.py +0 -0
- teddy_executor/adapters/inbound/__init__.py +0 -0
- teddy_executor/adapters/inbound/cli_formatter.py +107 -0
- teddy_executor/adapters/inbound/cli_helpers.py +249 -0
- teddy_executor/adapters/inbound/console_plan_reviewer.py +69 -0
- teddy_executor/adapters/inbound/session_cli_handlers.py +366 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer.py +78 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer_app.py +367 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer_editor.py +281 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer_execution.py +213 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer_helpers.py +308 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer_logic.py +345 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer_previews.py +227 -0
- teddy_executor/adapters/inbound/textual_plan_reviewer_widgets.py +246 -0
- teddy_executor/adapters/outbound/__init__.py +7 -0
- teddy_executor/adapters/outbound/console_interactor.py +212 -0
- teddy_executor/adapters/outbound/console_interactor_ask_loop.py +121 -0
- teddy_executor/adapters/outbound/console_interactor_helpers.py +95 -0
- teddy_executor/adapters/outbound/console_tooling.py +62 -0
- teddy_executor/adapters/outbound/filesystem_helpers.py +61 -0
- teddy_executor/adapters/outbound/litellm_adapter.py +462 -0
- teddy_executor/adapters/outbound/local_file_system_adapter.py +300 -0
- teddy_executor/adapters/outbound/local_repo_tree_generator.py +96 -0
- teddy_executor/adapters/outbound/openrouter_hydrator.py +89 -0
- teddy_executor/adapters/outbound/shell_adapter.py +344 -0
- teddy_executor/adapters/outbound/shell_command_builder.py +105 -0
- teddy_executor/adapters/outbound/system_environment_adapter.py +62 -0
- teddy_executor/adapters/outbound/system_environment_inspector.py +54 -0
- teddy_executor/adapters/outbound/system_time_adapter.py +22 -0
- teddy_executor/adapters/outbound/web_scraper_adapter.py +346 -0
- teddy_executor/adapters/outbound/web_searcher_adapter.py +122 -0
- teddy_executor/adapters/outbound/yaml_config_adapter.py +105 -0
- teddy_executor/container.py +333 -0
- teddy_executor/core/__init__.py +0 -0
- teddy_executor/core/domain/__init__.py +0 -0
- teddy_executor/core/domain/models/__init__.py +44 -0
- teddy_executor/core/domain/models/action_ports.py +28 -0
- teddy_executor/core/domain/models/change_set.py +10 -0
- teddy_executor/core/domain/models/exceptions.py +40 -0
- teddy_executor/core/domain/models/execution_report.py +65 -0
- teddy_executor/core/domain/models/orchestrator_ports.py +26 -0
- teddy_executor/core/domain/models/plan.py +85 -0
- teddy_executor/core/domain/models/planning_ports.py +43 -0
- teddy_executor/core/domain/models/project_context.py +56 -0
- teddy_executor/core/domain/models/report_assembly_data.py +18 -0
- teddy_executor/core/domain/models/session.py +17 -0
- teddy_executor/core/domain/models/shell_output.py +12 -0
- teddy_executor/core/domain/models/web_search_results.py +26 -0
- teddy_executor/core/ports/__init__.py +0 -0
- teddy_executor/core/ports/inbound/__init__.py +0 -0
- teddy_executor/core/ports/inbound/edit_simulator.py +33 -0
- teddy_executor/core/ports/inbound/get_context_use_case.py +32 -0
- teddy_executor/core/ports/inbound/init.py +15 -0
- teddy_executor/core/ports/inbound/plan_parser.py +52 -0
- teddy_executor/core/ports/inbound/plan_reviewer.py +44 -0
- teddy_executor/core/ports/inbound/plan_validator.py +26 -0
- teddy_executor/core/ports/inbound/planning_use_case.py +30 -0
- teddy_executor/core/ports/inbound/run_plan_use_case.py +60 -0
- teddy_executor/core/ports/outbound/__init__.py +34 -0
- teddy_executor/core/ports/outbound/config_service.py +29 -0
- teddy_executor/core/ports/outbound/environment_inspector.py +30 -0
- teddy_executor/core/ports/outbound/execution_report_assembler.py +19 -0
- teddy_executor/core/ports/outbound/file_system_manager.py +131 -0
- teddy_executor/core/ports/outbound/llm_client.py +90 -0
- teddy_executor/core/ports/outbound/markdown_report_formatter.py +26 -0
- teddy_executor/core/ports/outbound/prompt_manager.py +55 -0
- teddy_executor/core/ports/outbound/repo_tree_generator.py +17 -0
- teddy_executor/core/ports/outbound/session_loop_guard.py +16 -0
- teddy_executor/core/ports/outbound/session_manager.py +97 -0
- teddy_executor/core/ports/outbound/session_repository.py +65 -0
- teddy_executor/core/ports/outbound/shell_executor.py +24 -0
- teddy_executor/core/ports/outbound/system_environment.py +25 -0
- teddy_executor/core/ports/outbound/time_service.py +28 -0
- teddy_executor/core/ports/outbound/user_interactor.py +126 -0
- teddy_executor/core/ports/outbound/web_scraper.py +24 -0
- teddy_executor/core/ports/outbound/web_searcher.py +25 -0
- teddy_executor/core/services/__init__.py +0 -0
- teddy_executor/core/services/action_changeset_builder.py +90 -0
- teddy_executor/core/services/action_diff_manager.py +110 -0
- teddy_executor/core/services/action_dispatcher.py +142 -0
- teddy_executor/core/services/action_executor.py +209 -0
- teddy_executor/core/services/action_factory.py +197 -0
- teddy_executor/core/services/action_parser_complex.py +216 -0
- teddy_executor/core/services/action_parser_strategies.py +84 -0
- teddy_executor/core/services/context_service.py +437 -0
- teddy_executor/core/services/edit_simulator.py +128 -0
- teddy_executor/core/services/execution_orchestrator.py +295 -0
- teddy_executor/core/services/execution_report_assembler.py +62 -0
- teddy_executor/core/services/init_service.py +80 -0
- teddy_executor/core/services/markdown_plan_parser.py +309 -0
- teddy_executor/core/services/markdown_report_formatter.py +143 -0
- teddy_executor/core/services/parser_infrastructure.py +222 -0
- teddy_executor/core/services/parser_metadata.py +153 -0
- teddy_executor/core/services/parser_reporting.py +267 -0
- teddy_executor/core/services/plan_validator.py +82 -0
- teddy_executor/core/services/planning_service.py +242 -0
- teddy_executor/core/services/prompt_manager.py +146 -0
- teddy_executor/core/services/session_lifecycle_manager.py +228 -0
- teddy_executor/core/services/session_loop_guard.py +46 -0
- teddy_executor/core/services/session_orchestrator.py +538 -0
- teddy_executor/core/services/session_planner.py +43 -0
- teddy_executor/core/services/session_pruning_service.py +438 -0
- teddy_executor/core/services/session_replanner.py +105 -0
- teddy_executor/core/services/session_repository.py +194 -0
- teddy_executor/core/services/session_service.py +529 -0
- teddy_executor/core/services/templates/execution_report.md.j2 +290 -0
- teddy_executor/core/services/validation_rules/__init__.py +4 -0
- teddy_executor/core/services/validation_rules/edit.py +207 -0
- teddy_executor/core/services/validation_rules/edit_matcher.py +247 -0
- teddy_executor/core/services/validation_rules/edit_matcher_heuristics.py +84 -0
- teddy_executor/core/services/validation_rules/execute.py +37 -0
- teddy_executor/core/services/validation_rules/filesystem.py +73 -0
- teddy_executor/core/services/validation_rules/helpers.py +178 -0
- teddy_executor/core/services/validation_rules/message.py +29 -0
- teddy_executor/core/utils/__init__.py +1 -0
- teddy_executor/core/utils/diff.py +57 -0
- teddy_executor/core/utils/io.py +75 -0
- teddy_executor/core/utils/markdown.py +131 -0
- teddy_executor/core/utils/serialization.py +39 -0
- teddy_executor/core/utils/string.py +351 -0
- teddy_executor/prompts.py +45 -0
- teddy_executor/registries/__init__.py +1 -0
- teddy_executor/registries/infrastructure.py +147 -0
- teddy_executor/registries/reviewer.py +57 -0
- teddy_executor/registries/validators.py +47 -0
- teddy_executor/resources/__init__.py +1 -0
- teddy_executor/resources/config/.gitignore +2 -0
- teddy_executor/resources/config/__init__.py +1 -0
- teddy_executor/resources/config/config.yaml +49 -0
- teddy_executor/resources/config/init.context +5 -0
- teddy_executor/resources/config/prompts/architect.xml +462 -0
- teddy_executor/resources/config/prompts/assistant.xml +336 -0
- teddy_executor/resources/config/prompts/debugger.xml +456 -0
- teddy_executor/resources/config/prompts/developer.xml +481 -0
- teddy_executor/resources/config/prompts/pathfinder.xml +502 -0
- teddy_executor/resources/config/prompts/prototyper.xml +425 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: teddy-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A local-first, file-based AI coding workflow that applies the UNIX philosophy to AI collaboration.
|
|
5
|
+
License: AGPL-3.0-only
|
|
6
|
+
Author: Raphael Atteritano
|
|
7
|
+
Requires-Python: >=3.11,<3.14
|
|
8
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Dist: aiohttp (>=3.14.0)
|
|
13
|
+
Requires-Dist: bandit (>=1.7.9,<1.8.0)
|
|
14
|
+
Requires-Dist: beautifulsoup4 (>=4.14.3,<5.0.0)
|
|
15
|
+
Requires-Dist: ddgs (>=9.10.0,<10.0.0)
|
|
16
|
+
Requires-Dist: detect-secrets (>=1.4,<2.0)
|
|
17
|
+
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
18
|
+
Requires-Dist: jinja2 (>=3.1.6,<4.0.0)
|
|
19
|
+
Requires-Dist: litellm (>=1.83.7,<2.0.0)
|
|
20
|
+
Requires-Dist: lxml (>=6.1.0,<7.0.0)
|
|
21
|
+
Requires-Dist: mistletoe (>=1.3.0,<2.0.0)
|
|
22
|
+
Requires-Dist: pathspec (>=0.12.1,<0.13.0)
|
|
23
|
+
Requires-Dist: pip-audit (>=2.7.3,<2.8.0)
|
|
24
|
+
Requires-Dist: playwright
|
|
25
|
+
Requires-Dist: punq (>=0.7.0,<0.8.0)
|
|
26
|
+
Requires-Dist: pyperclip
|
|
27
|
+
Requires-Dist: python-dotenv (>=1.0.1)
|
|
28
|
+
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
29
|
+
Requires-Dist: requests (>=2.33.0,<3.0.0)
|
|
30
|
+
Requires-Dist: textual (>=8.1.0,<9.0.0)
|
|
31
|
+
Requires-Dist: trafilatura (>=2.0.0,<3.0.0)
|
|
32
|
+
Requires-Dist: typer[all]
|
|
33
|
+
Requires-Dist: urllib3 (>=2.7.0,<3.0.0)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
teddy_executor/__init__.py,sha256=xZ4r3lFwNLQ4C4vOl7Q_-5dh3TlWw3-nXR8O8yjV2o0,58
|
|
2
|
+
teddy_executor/__main__.py,sha256=Zt--RYeJI2SAaZVkhmZ35dXfKPfb_rYzCzvPrY1OqZw,11242
|
|
3
|
+
teddy_executor/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
teddy_executor/adapters/inbound/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
teddy_executor/adapters/inbound/cli_formatter.py,sha256=9bWL2S-3vZFBJZPd4RG2xTBYWu1Tim6U0AMGRjcUHB8,3548
|
|
6
|
+
teddy_executor/adapters/inbound/cli_helpers.py,sha256=xDJgnHijkA-iTXS10mx5FTrOMlk1iI1Vsn4eDPMNGcQ,8392
|
|
7
|
+
teddy_executor/adapters/inbound/console_plan_reviewer.py,sha256=Zi8wwxJNOHiB7iVeX346r6XHJDUWTukVGqEMHFQvDE8,2173
|
|
8
|
+
teddy_executor/adapters/inbound/session_cli_handlers.py,sha256=3hG8fl7z51JnvidXlJMbSW3X0kBrqCCyYbL2mD2IGLU,14155
|
|
9
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer.py,sha256=YszopR-mQpatQi79ssOtw5XfKTKiYsOCWxyVBOMgd6U,2774
|
|
10
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer_app.py,sha256=zrLTDRXApsrorOp6vBjNioiPSD98fkwa0xzp6R0cfMs,13755
|
|
11
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer_editor.py,sha256=NV2zCDIMwKqbizmWHM_gLPSBigp4h7lz8msgCeuEUTM,9649
|
|
12
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer_execution.py,sha256=LvMvPn5qiwf25dN5XnA-bEgkgBqOl7pkAy-FfnOQl9E,7222
|
|
13
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer_helpers.py,sha256=tayFz5r2PLRlVxfbYo-TGKpJTM9i6yroc5bTtUmt8B8,11647
|
|
14
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer_logic.py,sha256=dYJQ-pQhSeECeSuGAadhzBTpSJmG9bGLj-ZQk7UMids,11374
|
|
15
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer_previews.py,sha256=D6ZG3pibkr69SetNknJrwD9ROWQvyGieS77Oy3qfU-Y,8203
|
|
16
|
+
teddy_executor/adapters/inbound/textual_plan_reviewer_widgets.py,sha256=_-pfFY_71m0s3tDKzqH_l28fF563V0h3cZXYPKvS2kI,7356
|
|
17
|
+
teddy_executor/adapters/outbound/__init__.py,sha256=YN-oxkFQlMVrj3YdAJoLKXA_uo91cSU4llc3UHJ1Ckg,157
|
|
18
|
+
teddy_executor/adapters/outbound/console_interactor.py,sha256=Pl7FeV2I3Lo2K7EbWuwZV5FML3FsbsibouYFazaTfb4,8381
|
|
19
|
+
teddy_executor/adapters/outbound/console_interactor_ask_loop.py,sha256=FC6RA1vg5DPN8Lm6vvKPTzu0W3ms3nC39WsWArw8kpM,4189
|
|
20
|
+
teddy_executor/adapters/outbound/console_interactor_helpers.py,sha256=JkLIfAmd9u9DcXh-MDy_KZLrgnZM5J9QoiE_dg10_uQ,3033
|
|
21
|
+
teddy_executor/adapters/outbound/console_tooling.py,sha256=oyCgf0E5rFnqcL6DN46H5W2DUi10HA8Wwk1JmPPgh9U,2361
|
|
22
|
+
teddy_executor/adapters/outbound/filesystem_helpers.py,sha256=09CUnJtrl2EVmqhC0mwJ5VA1kcZJc53ntoj9ttvZuw8,1780
|
|
23
|
+
teddy_executor/adapters/outbound/litellm_adapter.py,sha256=xpLGNA0W18GDFEHZg_w3UMTqAEWjzsQIIS-h85MqWfA,18194
|
|
24
|
+
teddy_executor/adapters/outbound/local_file_system_adapter.py,sha256=hi32bvYNVz2tgLjEjTOPL9JVj_sq55-BrKR5SN6O9Oc,11063
|
|
25
|
+
teddy_executor/adapters/outbound/local_repo_tree_generator.py,sha256=8SRQmQf1UX4ucwOh8_5vrbGjZnJKX6cY93Cic4LZnZs,3264
|
|
26
|
+
teddy_executor/adapters/outbound/openrouter_hydrator.py,sha256=5WycqzprvuAR6tsKc6Yke_iCSO3r1bhMCm3CfVfh3tI,3496
|
|
27
|
+
teddy_executor/adapters/outbound/shell_adapter.py,sha256=72P-MvkEno1E2ZbmQqLtBCc_d5Qgj5anpbbaabPB_v4,13183
|
|
28
|
+
teddy_executor/adapters/outbound/shell_command_builder.py,sha256=HnnAHRj7pBk-V2grjVy7ZMvMkmBlZY0gWpP1EX73B7k,3960
|
|
29
|
+
teddy_executor/adapters/outbound/system_environment_adapter.py,sha256=4tE-rwVWHMQ_9spJBZc3-3WFGXehOWcZKQ3yz-hvFic,2179
|
|
30
|
+
teddy_executor/adapters/outbound/system_environment_inspector.py,sha256=7JORQnENa9NNJBF-YvRyvxzZR_elMVCdDQyI1CCmqPQ,1629
|
|
31
|
+
teddy_executor/adapters/outbound/system_time_adapter.py,sha256=q2Kbe1kMk4mybijYaMZFrjqo7Bff9AQUUKXZ2Ei7Siw,627
|
|
32
|
+
teddy_executor/adapters/outbound/web_scraper_adapter.py,sha256=HePgcVaE0lG-X2S_ZLLoudv3sp5ZEPu27XMebY7EChs,13243
|
|
33
|
+
teddy_executor/adapters/outbound/web_searcher_adapter.py,sha256=XHkIN9RvbzHkiVzQZYbdI3KJavO0zFNGW7jgC4gHrz0,4546
|
|
34
|
+
teddy_executor/adapters/outbound/yaml_config_adapter.py,sha256=1qs73GUj6JvHZ-LWFnoYzBGgTVG3_ogVFbSkBHCVlsI,3716
|
|
35
|
+
teddy_executor/container.py,sha256=xek1ZR7Xc-z95XnIpTl_h87na-4KXWUZcC0OHGPThW8,13423
|
|
36
|
+
teddy_executor/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
+
teddy_executor/core/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
+
teddy_executor/core/domain/models/__init__.py,sha256=yok7EZ3_cUwVGPGjBwTLg-zL4XTyQs2xAi_4VPKdKCk,1062
|
|
39
|
+
teddy_executor/core/domain/models/action_ports.py,sha256=vCMBtLS1thqT1YcGRScwapQ9MXKbvKg3zWeEGpJ5IhE,733
|
|
40
|
+
teddy_executor/core/domain/models/change_set.py,sha256=FgR553--lmcX-3tqjEkRhpwPpvEnLXWZ14Vkc2XgV_k,207
|
|
41
|
+
teddy_executor/core/domain/models/exceptions.py,sha256=kR6-vUECe06kVem0KoeHo9OEdQIFFB2AP58eWNo9qYs,1243
|
|
42
|
+
teddy_executor/core/domain/models/execution_report.py,sha256=QH-vku88XQ6FrHuV_d4_IbCXrSeg7WK9ybNlr35wqtE,1737
|
|
43
|
+
teddy_executor/core/domain/models/orchestrator_ports.py,sha256=zdfPXOUFmN9Zicwn5YI6sTWpcHeaCyABBoLKl-w2zNk,1039
|
|
44
|
+
teddy_executor/core/domain/models/plan.py,sha256=J2fgkY2OOOJ2HXHmfrey0O8rDPCezw-047us-3V3qGc,2284
|
|
45
|
+
teddy_executor/core/domain/models/planning_ports.py,sha256=qFz_177i8HkUmzwMNDLzuS3W7aCmkyVERdpSCKfQ_AE,1592
|
|
46
|
+
teddy_executor/core/domain/models/project_context.py,sha256=5uXtnjm9EUp3uLCxxWKwVEAhwOlXgUcbiUxhS35FbzA,1694
|
|
47
|
+
teddy_executor/core/domain/models/report_assembly_data.py,sha256=HuLqpha3cZ_V7BZ8pdsdIxnxVvCJ8_-o30PQVdkydrE,432
|
|
48
|
+
teddy_executor/core/domain/models/session.py,sha256=TlzoMHr5J4qd2QHrS5K1YXvt5g4xjYNQjSMfWdx4sVY,419
|
|
49
|
+
teddy_executor/core/domain/models/shell_output.py,sha256=wmOqFzIKETAzyWFUc0smZ8N-hh3OBQsy5VHqIhitKbA,267
|
|
50
|
+
teddy_executor/core/domain/models/web_search_results.py,sha256=ZugVr76XB2QdS-vumtPxY5h9Y5EP8bctn7tefIIWkhw,578
|
|
51
|
+
teddy_executor/core/ports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
|
+
teddy_executor/core/ports/inbound/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
+
teddy_executor/core/ports/inbound/edit_simulator.py,sha256=Pu4tBJxK4ensZO1gH_YE_NuVMG99qzy6v5Q4pN_VT5s,1087
|
|
54
|
+
teddy_executor/core/ports/inbound/get_context_use_case.py,sha256=aqVSP-XsSuQa4tDLUdThHGjJr2Q8MPTYhs34MZbo-Ec,1098
|
|
55
|
+
teddy_executor/core/ports/inbound/init.py,sha256=eJ8W_hcSeggZBt1vZ87pvDKfMCFnOJh9NpBHY5-h9_4,349
|
|
56
|
+
teddy_executor/core/ports/inbound/plan_parser.py,sha256=BaH1XQM23ys6l4YMcb2VTXs7IjW2TgklUqQ-8dthSYQ,1603
|
|
57
|
+
teddy_executor/core/ports/inbound/plan_reviewer.py,sha256=iHJfl4P7P6kOr2QERBAuXRaQwtgE7eiqOdQDpeMotmY,1247
|
|
58
|
+
teddy_executor/core/ports/inbound/plan_validator.py,sha256=hKwpYeAHVf04mFvG8ofN9jkItxiCsW1mB4Er6lqFIPY,732
|
|
59
|
+
teddy_executor/core/ports/inbound/planning_use_case.py,sha256=-33ypPVn__rcPzz3E0nJc_jIfAxcPc5VK9dYkoqJEMc,899
|
|
60
|
+
teddy_executor/core/ports/inbound/run_plan_use_case.py,sha256=EKLdQUqJE0sSZnuLiUWdk5hHEYPlE-i_9eY4vd9fAvs,2166
|
|
61
|
+
teddy_executor/core/ports/outbound/__init__.py,sha256=9jIaHAj9TPwR91-6CHskktKjsnEJHjXltZoZUwf2T54,1109
|
|
62
|
+
teddy_executor/core/ports/outbound/config_service.py,sha256=zfrSM9sUMprBmGavcEsU2n040TS0Vv3zkQ2iOtEKyBI,777
|
|
63
|
+
teddy_executor/core/ports/outbound/environment_inspector.py,sha256=q9UGud-2IAu1esBI3P95_tduEu8EZ6a1TDh1JjKjfu0,822
|
|
64
|
+
teddy_executor/core/ports/outbound/execution_report_assembler.py,sha256=dKfnE5dvUy_tlpJOIti307KfQEa2FIByZqpYK6TmBPs,521
|
|
65
|
+
teddy_executor/core/ports/outbound/file_system_manager.py,sha256=r2HcbU5dFyas4y9pjPGRWWBNmQZvMDDLRqEFc8bVlz4,3674
|
|
66
|
+
teddy_executor/core/ports/outbound/llm_client.py,sha256=CD4ix9tw91NLffSGJsEyyiGSrrX-z8jOFps417c4aO0,2625
|
|
67
|
+
teddy_executor/core/ports/outbound/markdown_report_formatter.py,sha256=KPfNxO0-Nmpsd6GrZe17jMcc78ND6h87rOolBC5vtrE,708
|
|
68
|
+
teddy_executor/core/ports/outbound/prompt_manager.py,sha256=7aLP7vg0rPt_j7BUif9q9TD4nGQ1Oe83ulDDwIbfAhk,1572
|
|
69
|
+
teddy_executor/core/ports/outbound/repo_tree_generator.py,sha256=DqicSWf8fHlsGOagFMTgpqO3IIPq2-spYmzELSrovTY,387
|
|
70
|
+
teddy_executor/core/ports/outbound/session_loop_guard.py,sha256=0XtUCG0i05M7ZroNzr8dcM73cUdD4SqdDlaVwyDQHv0,412
|
|
71
|
+
teddy_executor/core/ports/outbound/session_manager.py,sha256=JQVlvh_jS8Ng1EP_JqB21ZZz67k_sa9aLaucGAVkqQ8,2894
|
|
72
|
+
teddy_executor/core/ports/outbound/session_repository.py,sha256=mv0WQ_l0BsjRRASdt5Zngjpm9g9lRcJ1eLoMrXCB0W8,2182
|
|
73
|
+
teddy_executor/core/ports/outbound/shell_executor.py,sha256=8PYG2GFC7Xph_RNH_IDNA8JtZF09TZZ0p9Rb2RoU77Y,629
|
|
74
|
+
teddy_executor/core/ports/outbound/system_environment.py,sha256=OACTKSr8_XLKcTtqUEFCrvMx2Hf9N8Xr0jIXfdgOyms,720
|
|
75
|
+
teddy_executor/core/ports/outbound/time_service.py,sha256=67gJ_HAclRoeDBAa2IFuznahd3DZ2cwVWidzeSGcSsk,651
|
|
76
|
+
teddy_executor/core/ports/outbound/user_interactor.py,sha256=sSIReHedwQQy7AQuVGD2A69d6_5CIzfi4ao6u5QHjkM,3556
|
|
77
|
+
teddy_executor/core/ports/outbound/web_scraper.py,sha256=PYjc2Pkvw89hEtfjwUcTJ1256Phok6xG6RhqyQvOy9Q,611
|
|
78
|
+
teddy_executor/core/ports/outbound/web_searcher.py,sha256=6S0h_PRn5VmRxbnpHmGVotHfFNuYsec-zcs9qlZSs-E,663
|
|
79
|
+
teddy_executor/core/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
+
teddy_executor/core/services/action_changeset_builder.py,sha256=HDbTANTVa-XugTQpMBgi4Q2be-WiXcm-oPUD7Nt13Cw,3092
|
|
81
|
+
teddy_executor/core/services/action_diff_manager.py,sha256=9i4N0vdbCAAvCEMzRUPN_mb73nXFbG7rhA_SQuUthk0,3702
|
|
82
|
+
teddy_executor/core/services/action_dispatcher.py,sha256=2nB8x3dkNO0g3iThEUL2DBYwdV-Zsaigo0FpBiU9CPU,4962
|
|
83
|
+
teddy_executor/core/services/action_executor.py,sha256=SZWX5LdERuI2fe5KkUnUm21LfzezkkibYQ50vRoemDs,8153
|
|
84
|
+
teddy_executor/core/services/action_factory.py,sha256=B_b64ZqjzeWOkQmg5_monlD9a5UrirwqxACOyTIqTZ0,8539
|
|
85
|
+
teddy_executor/core/services/action_parser_complex.py,sha256=k3cbYPqdnrCRGXHTH9hjpa6hgFkh4P88_7wOi9jW0z0,6795
|
|
86
|
+
teddy_executor/core/services/action_parser_strategies.py,sha256=4yzjmpN_Vj76ag9jz2ZkFTu7bWbssUFhrAGNmUwKtP8,2601
|
|
87
|
+
teddy_executor/core/services/context_service.py,sha256=2Y8IitrzoKG44xQqMQ6V_Ed4ejJaflGJmK9_uLm8jII,16706
|
|
88
|
+
teddy_executor/core/services/edit_simulator.py,sha256=5L-Ji3dPkiW7qea0f5LTqY92xa0blLrC2_paK_PvhTY,4861
|
|
89
|
+
teddy_executor/core/services/execution_orchestrator.py,sha256=JX_-AxhMbOYOOjoa28t8oK58ihzMOLvw1UwWwt5fpGE,11118
|
|
90
|
+
teddy_executor/core/services/execution_report_assembler.py,sha256=QuperPp8GjQyky6eMm2oS7qyJnDYJqMWBBi4XkUV2-k,2041
|
|
91
|
+
teddy_executor/core/services/init_service.py,sha256=L_tlL4TptDMMSTlXOKI1bUtT0mfOC7uYgIjwS4Wmb5s,3252
|
|
92
|
+
teddy_executor/core/services/markdown_plan_parser.py,sha256=Owj1GJccUCH6XfO4ry95IQSytGmLFFyOTqXjpQuVjAo,11850
|
|
93
|
+
teddy_executor/core/services/markdown_report_formatter.py,sha256=xQRg_tkIRKVXUzmjcvkjYz3A-v4ecj9VfHaLRHDjIjw,5244
|
|
94
|
+
teddy_executor/core/services/parser_infrastructure.py,sha256=_2OwbA8KzLZ_3qaz-PG0NxVv-Xx_qbFooQtkqJClHDY,7461
|
|
95
|
+
teddy_executor/core/services/parser_metadata.py,sha256=KZY0nPz3NGogzY4ZfBQV9a-R0cwqoG3U3kdXaqpdXf0,5335
|
|
96
|
+
teddy_executor/core/services/parser_reporting.py,sha256=3Mw9mJdlaccdXOKZwgh98XdWLzTDZy91D50k2V6fgXo,9478
|
|
97
|
+
teddy_executor/core/services/plan_validator.py,sha256=fHCuMo3ETkJgP5Nbcy0JuFGucUyk5Pgo-GoQB7XPiT0,2906
|
|
98
|
+
teddy_executor/core/services/planning_service.py,sha256=QCIJ1z4gWtViwFgS9zCItrOhzzlimX0qBSxXfGUdEfM,9593
|
|
99
|
+
teddy_executor/core/services/prompt_manager.py,sha256=_PBL6lmeyi3DlMaw158mqRZRCmEbKP4-zrwsVefvJ4c,5905
|
|
100
|
+
teddy_executor/core/services/session_lifecycle_manager.py,sha256=XqmjSS64bFrMXTZEuZp8r6RDLGFYglk5ildLp3KL_kc,8822
|
|
101
|
+
teddy_executor/core/services/session_loop_guard.py,sha256=6RUg2Nb7rjf6VSybouyWc_qbKQ0n-JDAGrm-zd7_6Eg,1354
|
|
102
|
+
teddy_executor/core/services/session_orchestrator.py,sha256=saDgG4veoNYHYinAkGtCTKOdaXG8nISKQ4DGRa2UBVo,20595
|
|
103
|
+
teddy_executor/core/services/session_planner.py,sha256=8zGmkAXHeblpX6WxJybB2_RKXMw0-2pKtrL7aNv0fIs,1420
|
|
104
|
+
teddy_executor/core/services/session_pruning_service.py,sha256=K-9SWr8urQE62XrrbnK4V14ylRIPxrCLGHnNYf6nu8c,16056
|
|
105
|
+
teddy_executor/core/services/session_replanner.py,sha256=HzXQz64RtXucB2tH8JbF6HPGGlAIMOnahcnLlAdG8Cs,3651
|
|
106
|
+
teddy_executor/core/services/session_repository.py,sha256=csKYPelvaZlehI54TZdfUE7SCq000EQ6M8U6VbiZ6Ss,7966
|
|
107
|
+
teddy_executor/core/services/session_service.py,sha256=I-I7lwmcSmrvp6U7RxzmDlcVG8N233ZjhPXYHVWGr8Q,21724
|
|
108
|
+
teddy_executor/core/services/templates/execution_report.md.j2,sha256=7sTvelTNwXmEx245gu33f5LsRrcbLPvzSNnf9qCMjGo,10706
|
|
109
|
+
teddy_executor/core/services/validation_rules/__init__.py,sha256=Pe0dCWgssakypne3Yi0R1UK_T7gn6WZjjAk7YHcLUT8,128
|
|
110
|
+
teddy_executor/core/services/validation_rules/edit.py,sha256=ab4RCrfr9PswBSwy9pAuA2MJO5W85VqeuJWAhd6mbzM,7536
|
|
111
|
+
teddy_executor/core/services/validation_rules/edit_matcher.py,sha256=3bTbpnd76ot1YjbHmGGbut1nlug6JCoYjdXNvPsHp_0,8509
|
|
112
|
+
teddy_executor/core/services/validation_rules/edit_matcher_heuristics.py,sha256=5rQ4B2Er0fR3DkdJEn5bjChUHaikIZ3oNlNgdtYGVPw,3007
|
|
113
|
+
teddy_executor/core/services/validation_rules/execute.py,sha256=EPCqsL-tWIC9VGezAxq-L52Nq1Mdi12CyeKM2n054sM,1023
|
|
114
|
+
teddy_executor/core/services/validation_rules/filesystem.py,sha256=lak5wr15Lox5DMznzkZ3ePKd7UszHwf5b_gEMe54BOI,2428
|
|
115
|
+
teddy_executor/core/services/validation_rules/helpers.py,sha256=RaL0_fIqxXWPNZYAqP2bq53wo9hVRoQ8Gs1rfMxy0dw,5889
|
|
116
|
+
teddy_executor/core/services/validation_rules/message.py,sha256=PiPpW5l9QDc_ojNxB98DKRvs4H9C9tht_uVo3iSWdik,838
|
|
117
|
+
teddy_executor/core/utils/__init__.py,sha256=4BK6udEIDfmM0CaTGO6kKHr1LbLChRfblcqBt44mekc,22
|
|
118
|
+
teddy_executor/core/utils/diff.py,sha256=7hhLIvETTbGJddNB7yx_12S0IJDekc6OzzfUesJRG4A,1786
|
|
119
|
+
teddy_executor/core/utils/io.py,sha256=XsmNajZ_Z30xbtArFlceMhggNQi8tH0nuw1dR4NeKdc,2502
|
|
120
|
+
teddy_executor/core/utils/markdown.py,sha256=kVa4SuP3x7ofESnPvAXPwlJf79C0k1LpDgnuwEJPMDI,3864
|
|
121
|
+
teddy_executor/core/utils/serialization.py,sha256=V_1jyPeRm670HlbIKhrW8LP1s6O4UCc8xo0kmky9EDs,1237
|
|
122
|
+
teddy_executor/core/utils/string.py,sha256=zYKR6XCipHsIXn15rTz9XR5CMwy02fcEXBcYQqQIFUo,7769
|
|
123
|
+
teddy_executor/prompts.py,sha256=dT5dJLt8Mp1h1XYo023C1kxMnUjWKSfdBSIT2BRBwvk,1749
|
|
124
|
+
teddy_executor/registries/__init__.py,sha256=Y9luGTza-JjAZCHGX7VJpyj55ijfrSJFrwYKgk0iwkE,52
|
|
125
|
+
teddy_executor/registries/infrastructure.py,sha256=-ViJA0UnvbSMrlvlaGkNi1pBk_wNc5u66jC6e2XQ91A,4875
|
|
126
|
+
teddy_executor/registries/reviewer.py,sha256=7LAqZ6wAqTpp4n1jOIfcwRa8MKueLJa9S_J2nrsGIC4,2200
|
|
127
|
+
teddy_executor/registries/validators.py,sha256=82SNpawuzWV2dtJcMAVP7wOpjoJ0hViR2a3kOwgIyIA,1907
|
|
128
|
+
teddy_executor/resources/__init__.py,sha256=h835ykuoc9Xv0E4UIaHmi8iVnhPKYqhwkLzHV5jRQEs,45
|
|
129
|
+
teddy_executor/resources/config/.gitignore,sha256=X8MZtMI-F4Ca0w-t5yVZ0UluMDow8tculFbbyZ4VDAk,57
|
|
130
|
+
teddy_executor/resources/config/__init__.py,sha256=R96a_JS3GOty_5vsGg8AcR3cQYotYXCELrIzWFhn4kE,61
|
|
131
|
+
teddy_executor/resources/config/config.yaml,sha256=aBwmlmq8Jfd9tcLptneLNtWD3SRlh2vMfgxY51vIcl4,1895
|
|
132
|
+
teddy_executor/resources/config/init.context,sha256=9J70exhvHAzqHX8kin2PuVtPi2JZp-TAzZr-PV8EYSg,87
|
|
133
|
+
teddy_executor/resources/config/prompts/architect.xml,sha256=hIPXgB4_Sd9HoXYn9xm9Slm6yG4q2567aqa3RBhMLvc,32574
|
|
134
|
+
teddy_executor/resources/config/prompts/assistant.xml,sha256=YkJ2zKI730ow4dze-ryi-SGn3lLSUCNlLMOslJRDWwM,20670
|
|
135
|
+
teddy_executor/resources/config/prompts/debugger.xml,sha256=Bwmwuc4jZ9H-474Q7V_onCcisYr__fLhGlNaesqrEPk,36369
|
|
136
|
+
teddy_executor/resources/config/prompts/developer.xml,sha256=hoQlHNSkNlr0HGHUbF8px_VnzsoKTkOuhE0KqI-uRk4,35366
|
|
137
|
+
teddy_executor/resources/config/prompts/pathfinder.xml,sha256=DMCJ0KuIAMy9f98dbCcft82qmGKSrin06VF_8EnEGC4,35603
|
|
138
|
+
teddy_executor/resources/config/prompts/prototyper.xml,sha256=YUKRaSUAkDxd_fQN_OWqEDWtKrNFyW_rOTXLhWntUYc,32900
|
|
139
|
+
teddy_cli-0.1.0.dist-info/LICENSE,sha256=HBL2C3ynq_mk-EYtJI7aXEc6gXnXgKJ-K6KZ13N0Ojs,35270
|
|
140
|
+
teddy_cli-0.1.0.dist-info/METADATA,sha256=CDKuOCsyzq5vz7MZpvFwt1bV8eXjU58UkYfEBSMgunc,1308
|
|
141
|
+
teddy_cli-0.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
142
|
+
teddy_cli-0.1.0.dist-info/entry_points.txt,sha256=M-SJf8_LfQpBkkx0RAk8jLEbz-lShhh-48vqMQXpK1k,53
|
|
143
|
+
teddy_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# This file makes the 'teddy' directory a Python package.
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING, Optional
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from teddy_executor.core.domain.models import (
|
|
12
|
+
ExecutionReport,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from teddy_executor.core.ports.inbound.plan_parser import IPlanParser
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
app = typer.Typer()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_container():
|
|
23
|
+
from teddy_executor.container import get_container as _get_container
|
|
24
|
+
|
|
25
|
+
return _get_container()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _apply_ui_mode_override(container, ui_mode_bool: bool) -> None:
|
|
29
|
+
from teddy_executor.container import register_reviewer
|
|
30
|
+
|
|
31
|
+
mode = "tui" if ui_mode_bool else "console"
|
|
32
|
+
register_reviewer(container, ui_mode=mode)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
logging.basicConfig(
|
|
36
|
+
level=logging.INFO,
|
|
37
|
+
format="%(message)s",
|
|
38
|
+
handlers=[logging.StreamHandler(sys.stderr)],
|
|
39
|
+
force=True,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _ensure_project_initialized(container) -> None:
|
|
44
|
+
"""Lazily performs project anchoring and initialization."""
|
|
45
|
+
from teddy_executor.adapters.inbound.cli_helpers import find_project_root
|
|
46
|
+
from teddy_executor.core.ports.outbound.file_system_manager import (
|
|
47
|
+
IFileSystemManager,
|
|
48
|
+
)
|
|
49
|
+
from teddy_executor.core.ports.outbound.repo_tree_generator import (
|
|
50
|
+
IRepoTreeGenerator,
|
|
51
|
+
)
|
|
52
|
+
from teddy_executor.adapters.outbound.local_file_system_adapter import (
|
|
53
|
+
LocalFileSystemAdapter,
|
|
54
|
+
)
|
|
55
|
+
from teddy_executor.adapters.outbound.local_repo_tree_generator import (
|
|
56
|
+
LocalRepoTreeGenerator,
|
|
57
|
+
)
|
|
58
|
+
from teddy_executor.core.ports.inbound.init import IInitUseCase
|
|
59
|
+
from teddy_executor.core.ports.outbound.config_service import IConfigService
|
|
60
|
+
from teddy_executor.adapters.outbound.yaml_config_adapter import YamlConfigAdapter
|
|
61
|
+
from punq import Scope
|
|
62
|
+
|
|
63
|
+
root = str(find_project_root())
|
|
64
|
+
c = container
|
|
65
|
+
|
|
66
|
+
regs = getattr(c.registrations, "_Registry__registrations", {})
|
|
67
|
+
|
|
68
|
+
def is_override(service_type) -> bool:
|
|
69
|
+
reg_list = regs.get(service_type)
|
|
70
|
+
return any(
|
|
71
|
+
reg.scope == Scope.singleton or hasattr(reg, "instance")
|
|
72
|
+
for reg in (reg_list or [])
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if not is_override(IFileSystemManager):
|
|
76
|
+
c.register(IFileSystemManager, LocalFileSystemAdapter, root_dir=root)
|
|
77
|
+
if not is_override(IRepoTreeGenerator):
|
|
78
|
+
c.register(IRepoTreeGenerator, LocalRepoTreeGenerator, root_dir=root)
|
|
79
|
+
if not is_override(IConfigService):
|
|
80
|
+
c.register(IConfigService, YamlConfigAdapter, root_dir=root)
|
|
81
|
+
|
|
82
|
+
c.resolve(IInitUseCase).ensure_initialized()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# Shared Typer options to reduce duplication for jscpd
|
|
86
|
+
OPT_NO_COPY = typer.Option(
|
|
87
|
+
False, "--no-copy", help="Do not copy the output to the clipboard."
|
|
88
|
+
)
|
|
89
|
+
OPT_UI_MODE = typer.Option(
|
|
90
|
+
None, "--tui/--console", help="Force TUI or Console mode.", show_default=False
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@app.command()
|
|
95
|
+
def start( # noqa: PLR0913
|
|
96
|
+
name: Optional[str] = typer.Argument(None, help="The name of the new session."),
|
|
97
|
+
agent: str = typer.Option(
|
|
98
|
+
"pathfinder", "--agent", "-a", help="Agent prompt to use."
|
|
99
|
+
),
|
|
100
|
+
yolo: bool = typer.Option(
|
|
101
|
+
False, "--yolo", "-y", help="Auto-approve all actions (non-interactive mode)."
|
|
102
|
+
),
|
|
103
|
+
yes: bool = typer.Option(False, "--yes", hidden=True),
|
|
104
|
+
no_interactive: bool = typer.Option(False, "--no-interactive", hidden=True),
|
|
105
|
+
non_interactive: bool = typer.Option(False, "--non-interactive", hidden=True),
|
|
106
|
+
no_copy: bool = OPT_NO_COPY,
|
|
107
|
+
ui_mode: Optional[bool] = OPT_UI_MODE,
|
|
108
|
+
message: Optional[str] = typer.Option(
|
|
109
|
+
None, "-m", "--message", help="Instruction for the first turn."
|
|
110
|
+
),
|
|
111
|
+
context: Optional[str] = typer.Option(
|
|
112
|
+
None,
|
|
113
|
+
"--context",
|
|
114
|
+
"-c",
|
|
115
|
+
help="Comma-separated list of additional files/dirs for context.",
|
|
116
|
+
),
|
|
117
|
+
model: Optional[str] = typer.Option(None, "--model", help="LLM model override."),
|
|
118
|
+
provider: Optional[str] = typer.Option(
|
|
119
|
+
None, "--provider", help="LLM provider override."
|
|
120
|
+
),
|
|
121
|
+
api_key: Optional[str] = typer.Option(
|
|
122
|
+
None, "--api-key", help="LLM API key override."
|
|
123
|
+
),
|
|
124
|
+
):
|
|
125
|
+
"""
|
|
126
|
+
Initializes a new session directory and bootstraps it for Turn 1.
|
|
127
|
+
"""
|
|
128
|
+
from teddy_executor.adapters.inbound.session_cli_handlers import handle_new_session
|
|
129
|
+
|
|
130
|
+
container = get_container()
|
|
131
|
+
_ensure_project_initialized(container)
|
|
132
|
+
if ui_mode is not None:
|
|
133
|
+
_apply_ui_mode_override(container, ui_mode)
|
|
134
|
+
|
|
135
|
+
additional_context = context.split(",") if context else None
|
|
136
|
+
|
|
137
|
+
handle_new_session(
|
|
138
|
+
container=container,
|
|
139
|
+
name=name,
|
|
140
|
+
agent=agent,
|
|
141
|
+
interactive=not (yolo or yes or no_interactive or non_interactive),
|
|
142
|
+
no_copy=no_copy,
|
|
143
|
+
message=message,
|
|
144
|
+
additional_context=additional_context,
|
|
145
|
+
model=model,
|
|
146
|
+
provider=provider,
|
|
147
|
+
api_key=api_key,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@app.command()
|
|
152
|
+
def init():
|
|
153
|
+
"""
|
|
154
|
+
Initializes the .teddy directory and pre-warms heavy imports for faster startup.
|
|
155
|
+
"""
|
|
156
|
+
container = get_container()
|
|
157
|
+
_ensure_project_initialized(container)
|
|
158
|
+
# Pre-warm heavy imports to reduce first-run latency
|
|
159
|
+
try:
|
|
160
|
+
import litellm # noqa: F401
|
|
161
|
+
import trafilatura # noqa: F401
|
|
162
|
+
import pyperclip # noqa: F401
|
|
163
|
+
from bs4 import BeautifulSoup # noqa: F401
|
|
164
|
+
from ddgs import DDGS # noqa: F401
|
|
165
|
+
except ImportError:
|
|
166
|
+
pass # Some optional dependencies may not be installed
|
|
167
|
+
# Auto-login would trigger here once `teddy login` is implemented (no-op for now)
|
|
168
|
+
typer.echo("TeDDy initialized in .teddy folder.")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@app.command()
|
|
172
|
+
def context(
|
|
173
|
+
no_copy: bool = typer.Option(
|
|
174
|
+
False,
|
|
175
|
+
"--no-copy",
|
|
176
|
+
help="Do not copy the output to the clipboard.",
|
|
177
|
+
),
|
|
178
|
+
):
|
|
179
|
+
"""
|
|
180
|
+
Gathers and displays project context (file tree + file contents).
|
|
181
|
+
|
|
182
|
+
All operations respect the project's root-relative path conventions.
|
|
183
|
+
"""
|
|
184
|
+
from teddy_executor.adapters.inbound.session_cli_handlers import (
|
|
185
|
+
handle_context_gathering,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
container = get_container()
|
|
189
|
+
_ensure_project_initialized(container)
|
|
190
|
+
handle_context_gathering(container, no_copy)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@app.command(name="get-prompt")
|
|
194
|
+
def get_prompt(
|
|
195
|
+
prompt_name: str = typer.Argument(..., help="The name of the prompt to retrieve."),
|
|
196
|
+
no_copy: bool = typer.Option(
|
|
197
|
+
False, "--no-copy", help="Do not copy the output to the clipboard."
|
|
198
|
+
),
|
|
199
|
+
):
|
|
200
|
+
"""
|
|
201
|
+
Retrieves and displays the content of a specified prompt.
|
|
202
|
+
|
|
203
|
+
Searches for root-relative overrides in ./.teddy/prompts/ before falling back to defaults.
|
|
204
|
+
"""
|
|
205
|
+
from teddy_executor.adapters.inbound.cli_helpers import echo_and_copy
|
|
206
|
+
from teddy_executor.prompts import find_prompt_content, list_prompt_names
|
|
207
|
+
|
|
208
|
+
prompt_content = find_prompt_content(prompt_name)
|
|
209
|
+
|
|
210
|
+
if prompt_content:
|
|
211
|
+
echo_and_copy(prompt_content, no_copy)
|
|
212
|
+
else:
|
|
213
|
+
available = list_prompt_names()
|
|
214
|
+
if available:
|
|
215
|
+
msg = f"Error: Prompt '{prompt_name}' not found. Available prompts: {', '.join(available)}"
|
|
216
|
+
else:
|
|
217
|
+
msg = f"Error: Prompt '{prompt_name}' not found."
|
|
218
|
+
typer.echo(msg, err=True)
|
|
219
|
+
raise typer.Exit(code=1)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def create_parser_for_plan(plan_content: str) -> IPlanParser:
|
|
223
|
+
"""
|
|
224
|
+
Factory function to determine which plan parser to use.
|
|
225
|
+
"""
|
|
226
|
+
# Legacy YAML plans are deprecated. Only Markdown is supported.
|
|
227
|
+
return get_container().resolve(IPlanParser)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@app.command()
|
|
231
|
+
def resume( # noqa: PLR0913
|
|
232
|
+
path: Optional[str] = typer.Argument(None, help="Path to session or turn."),
|
|
233
|
+
yolo: bool = typer.Option(
|
|
234
|
+
False, "--yolo", "-y", help="Auto-approve all actions (non-interactive mode)."
|
|
235
|
+
),
|
|
236
|
+
yes: bool = typer.Option(False, "--yes", hidden=True),
|
|
237
|
+
no_interactive: bool = typer.Option(False, "--no-interactive", hidden=True),
|
|
238
|
+
non_interactive: bool = typer.Option(False, "--non-interactive", hidden=True),
|
|
239
|
+
no_copy: bool = OPT_NO_COPY,
|
|
240
|
+
ui_mode: Optional[bool] = OPT_UI_MODE,
|
|
241
|
+
model: Optional[str] = typer.Option(None, "--model", help="LLM model override."),
|
|
242
|
+
provider: Optional[str] = typer.Option(
|
|
243
|
+
None, "--provider", help="LLM provider override."
|
|
244
|
+
),
|
|
245
|
+
api_key: Optional[str] = typer.Option(
|
|
246
|
+
None, "--api-key", help="LLM API key override."
|
|
247
|
+
),
|
|
248
|
+
):
|
|
249
|
+
"""
|
|
250
|
+
Intelligently resumes the last turn of a session or starts a new one.
|
|
251
|
+
"""
|
|
252
|
+
from teddy_executor.adapters.inbound.cli_helpers import apply_ui_mode_override
|
|
253
|
+
from teddy_executor.adapters.inbound.session_cli_handlers import (
|
|
254
|
+
handle_resume_session,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
container = get_container()
|
|
258
|
+
_ensure_project_initialized(container)
|
|
259
|
+
if ui_mode is not None:
|
|
260
|
+
apply_ui_mode_override(container, ui_mode)
|
|
261
|
+
|
|
262
|
+
handle_resume_session(
|
|
263
|
+
container=container,
|
|
264
|
+
path=path,
|
|
265
|
+
interactive=not (yolo or yes or no_interactive or non_interactive),
|
|
266
|
+
no_copy=no_copy,
|
|
267
|
+
model=model,
|
|
268
|
+
provider=provider,
|
|
269
|
+
api_key=api_key,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@app.command()
|
|
274
|
+
def execute( # noqa: PLR0913
|
|
275
|
+
plan_file: Optional[Path] = typer.Argument(
|
|
276
|
+
None, help="Root-relative path to the plan file (.md).", show_default=False
|
|
277
|
+
),
|
|
278
|
+
yolo: bool = typer.Option(
|
|
279
|
+
False, "--yolo", "-y", help="Auto-approve all actions (non-interactive mode)."
|
|
280
|
+
),
|
|
281
|
+
yes: bool = typer.Option(False, "--yes", hidden=True),
|
|
282
|
+
no_interactive: bool = typer.Option(False, "--no-interactive", hidden=True),
|
|
283
|
+
non_interactive: bool = typer.Option(False, "--non-interactive", hidden=True),
|
|
284
|
+
no_copy: bool = OPT_NO_COPY,
|
|
285
|
+
plan_content: Optional[str] = typer.Option(
|
|
286
|
+
None, "--plan-content", help="Plan content.", show_default=False
|
|
287
|
+
),
|
|
288
|
+
ui_mode: Optional[bool] = OPT_UI_MODE,
|
|
289
|
+
message: Optional[str] = typer.Option(
|
|
290
|
+
None, "-m", "--message", help="Optional instruction for the report."
|
|
291
|
+
),
|
|
292
|
+
):
|
|
293
|
+
"""
|
|
294
|
+
Executes a Markdown plan file (from path or clipboard) and generates an execution report.
|
|
295
|
+
"""
|
|
296
|
+
from teddy_executor.adapters.inbound.cli_helpers import (
|
|
297
|
+
apply_ui_mode_override,
|
|
298
|
+
get_plan_content,
|
|
299
|
+
handle_report_output,
|
|
300
|
+
)
|
|
301
|
+
from teddy_executor.core.ports.inbound.plan_parser import InvalidPlanError
|
|
302
|
+
from teddy_executor.core.ports.inbound.run_plan_use_case import IRunPlanUseCase
|
|
303
|
+
|
|
304
|
+
report: Optional[ExecutionReport] = None
|
|
305
|
+
interactive_mode = not (yolo or yes or no_interactive or non_interactive)
|
|
306
|
+
start_time = datetime.now(timezone.utc)
|
|
307
|
+
|
|
308
|
+
container = get_container()
|
|
309
|
+
_ensure_project_initialized(container)
|
|
310
|
+
if ui_mode is not None:
|
|
311
|
+
apply_ui_mode_override(container, ui_mode)
|
|
312
|
+
|
|
313
|
+
try:
|
|
314
|
+
final_plan_content = get_plan_content(plan_content, plan_file)
|
|
315
|
+
orchestrator = container.resolve(IRunPlanUseCase)
|
|
316
|
+
|
|
317
|
+
report = orchestrator.execute(
|
|
318
|
+
plan_content=final_plan_content,
|
|
319
|
+
plan_path=str(plan_file) if plan_file else None,
|
|
320
|
+
interactive=interactive_mode,
|
|
321
|
+
message=message,
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
except (InvalidPlanError, NotImplementedError) as e:
|
|
325
|
+
from teddy_executor.adapters.inbound.cli_helpers import create_failure_report
|
|
326
|
+
|
|
327
|
+
report = create_failure_report(
|
|
328
|
+
e, start_time, container, plan_content=final_plan_content
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
handle_report_output(container, report, no_copy)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
if __name__ == "__main__":
|
|
335
|
+
app()
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import difflib
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from teddy_executor.core.domain.models import (
|
|
7
|
+
ActionData,
|
|
8
|
+
ChangeSet,
|
|
9
|
+
Plan,
|
|
10
|
+
ProjectContext,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def format_project_context(context: ProjectContext) -> str:
|
|
15
|
+
"""
|
|
16
|
+
Formats the ProjectContext DTO into a single string for display.
|
|
17
|
+
The actual formatting is now done in the ContextService. This function
|
|
18
|
+
simply combines the pre-formatted parts.
|
|
19
|
+
"""
|
|
20
|
+
return f"{context.header}\n{context.content}"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def echo_handoff_details(
|
|
24
|
+
action_type: str,
|
|
25
|
+
target_agent: Optional[str],
|
|
26
|
+
resources: List[str],
|
|
27
|
+
message: str,
|
|
28
|
+
):
|
|
29
|
+
"""Prints formatted handoff details to the terminal."""
|
|
30
|
+
if action_type == "INVOKE":
|
|
31
|
+
typer.secho("--- HANDOFF REQUEST ---", fg=typer.colors.CYAN, err=True)
|
|
32
|
+
typer.echo(
|
|
33
|
+
"The current agent is requesting a handoff to the agent below.\n",
|
|
34
|
+
err=True,
|
|
35
|
+
)
|
|
36
|
+
if target_agent:
|
|
37
|
+
typer.echo(f"▶ Target Agent: {target_agent}", err=True)
|
|
38
|
+
typer.echo(f"▶ Handoff Message:\n{message}\n", err=True)
|
|
39
|
+
else: # RETURN
|
|
40
|
+
typer.secho("--- HANDOFF NOTIFICATION ---", fg=typer.colors.CYAN, err=True)
|
|
41
|
+
typer.echo(
|
|
42
|
+
"The current agent has completed its task and is returning control.\n",
|
|
43
|
+
err=True,
|
|
44
|
+
)
|
|
45
|
+
typer.echo(f"▶ Return Message:\n{message}\n", err=True)
|
|
46
|
+
|
|
47
|
+
if resources:
|
|
48
|
+
typer.echo("▶ Reference Files:", err=True)
|
|
49
|
+
typer.echo("\n".join(resources), err=True)
|
|
50
|
+
typer.echo("", err=True)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def echo_diff_preview(change_set: ChangeSet):
|
|
54
|
+
"""Prints a terminal-formatted diff or file preview."""
|
|
55
|
+
if change_set.action_type == "CREATE":
|
|
56
|
+
typer.echo("--- New File Preview ---", err=True)
|
|
57
|
+
typer.echo(f"Path: {change_set.path}", err=True)
|
|
58
|
+
typer.echo("Content:", err=True)
|
|
59
|
+
typer.echo(change_set.after_content, err=True)
|
|
60
|
+
typer.echo("------------------------", err=True)
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
diff_generator = difflib.unified_diff(
|
|
64
|
+
change_set.before_content.splitlines(keepends=True),
|
|
65
|
+
change_set.after_content.splitlines(keepends=True),
|
|
66
|
+
fromfile=f"a/{change_set.path.name}",
|
|
67
|
+
tofile=f"b/{change_set.path.name}",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
diff_lines = []
|
|
71
|
+
for line in diff_generator:
|
|
72
|
+
diff_lines.append(line)
|
|
73
|
+
if not line.endswith("\n"):
|
|
74
|
+
diff_lines.append("\n")
|
|
75
|
+
|
|
76
|
+
typer.echo("--- Diff ---", err=True)
|
|
77
|
+
typer.echo("".join(diff_lines).rstrip(), err=True)
|
|
78
|
+
typer.echo("------------", err=True)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def echo_plan_summary(plan: Plan):
|
|
82
|
+
"""Prints a summary of the plan's actions to the terminal."""
|
|
83
|
+
header = f'\n▶ Reviewing Plan: "{plan.title}"'
|
|
84
|
+
typer.secho(header, fg=typer.colors.CYAN, bold=True, err=True)
|
|
85
|
+
typer.echo("-" * 68, err=True)
|
|
86
|
+
|
|
87
|
+
counts: dict[str, int] = {}
|
|
88
|
+
for action in plan.actions:
|
|
89
|
+
counts[action.type] = counts.get(action.type, 0) + 1
|
|
90
|
+
|
|
91
|
+
typer.echo("\n Action Plan:", err=True)
|
|
92
|
+
for action_type in sorted(counts.keys()):
|
|
93
|
+
count = counts[action_type]
|
|
94
|
+
label = "action" if count == 1 else "actions"
|
|
95
|
+
typer.echo(f" - {action_type}: {count} {label}", err=True)
|
|
96
|
+
typer.echo("\n" + "-" * 68, err=True)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def echo_skipped_action(action: ActionData, reason: str):
|
|
100
|
+
"""Prints a colorized skip notification."""
|
|
101
|
+
message = f"[SKIPPED] {action.type}: {reason}"
|
|
102
|
+
typer.secho(message, fg=typer.colors.YELLOW, err=True)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def style_text(text: str, style: str) -> str:
|
|
106
|
+
"""Wraps text in Rich style tags."""
|
|
107
|
+
return f"[{style}]{text}[/]"
|