ara-cli 0.1.10.1__tar.gz → 0.1.10.8__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.

Potentially problematic release.


This version of ara-cli might be problematic. Click here for more details.

Files changed (218) hide show
  1. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/PKG-INFO +31 -1
  2. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/README.md +29 -0
  3. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/__init__.py +0 -1
  4. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/__main__.py +95 -2
  5. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_autofix.py +44 -6
  6. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/artefact_model.py +18 -6
  7. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/artefact_templates.py +2 -1
  8. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/epic_artefact_model.py +11 -2
  9. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/feature_artefact_model.py +31 -1
  10. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/userstory_artefact_model.py +13 -1
  11. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/chat.py +142 -37
  12. ara_cli-0.1.10.8/ara_cli/chat_agent/agent_communicator.py +62 -0
  13. ara_cli-0.1.10.8/ara_cli/chat_agent/agent_process_manager.py +211 -0
  14. ara_cli-0.1.10.8/ara_cli/chat_agent/agent_status_manager.py +73 -0
  15. ara_cli-0.1.10.8/ara_cli/chat_agent/agent_workspace_manager.py +76 -0
  16. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/directory_navigator.py +37 -4
  17. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/text_file_loader.py +2 -2
  18. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/global_file_lister.py +5 -15
  19. ara_cli-0.1.10.8/ara_cli/prompt_extractor.py +338 -0
  20. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/prompt_handler.py +160 -59
  21. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/tag_extractor.py +26 -23
  22. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/template_loader.py +1 -1
  23. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/empty.commands.md +4 -0
  24. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/extract_general.commands.md +12 -0
  25. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/extract_markdown.commands.md +11 -0
  26. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/extract_python.commands.md +13 -0
  27. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/feature_add_or_modifiy_specified_behavior.commands.md +36 -0
  28. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/feature_generate_initial_specified_bevahior.commands.md +53 -0
  29. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/prompt_template_tech_stack_transformer.commands.md +95 -0
  30. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/python_bug_fixing_code.commands.md +34 -0
  31. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/python_generate_code.commands.md +27 -0
  32. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/python_refactoring_code.commands.md +39 -0
  33. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/python_step_definitions_generation_and_fixing.commands.md +40 -0
  34. ara_cli-0.1.10.8/ara_cli/templates/prompt-modules/commands/python_unittest_generation_and_fixing.commands.md +48 -0
  35. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/version.py +1 -1
  36. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli.egg-info/PKG-INFO +31 -1
  37. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli.egg-info/SOURCES.txt +16 -16
  38. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli.egg-info/requires.txt +1 -0
  39. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/docker/base/requirements.txt +3 -1
  40. ara_cli-0.1.10.8/tests/__init__.py +0 -0
  41. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_global_file_lister.py +1 -1
  42. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_prompt_handler.py +12 -4
  43. ara_cli-0.1.10.1/ara_cli/prompt_extractor.py +0 -230
  44. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -27
  45. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -30
  46. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -9
  47. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -17
  48. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -14
  49. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -102
  50. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -20
  51. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -13
  52. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/empty.commands.md +0 -14
  53. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -20
  54. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -18
  55. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -43
  56. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -13
  57. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -15
  58. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -9
  59. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -15
  60. ara_cli-0.1.10.1/ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -19
  61. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/MANIFEST.in +0 -0
  62. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_command_action.py +0 -0
  63. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_config.py +0 -0
  64. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/__init__.py +0 -0
  65. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/autofix.py +0 -0
  66. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/chat.py +0 -0
  67. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/classifier_directory.py +0 -0
  68. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/common.py +0 -0
  69. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/create.py +0 -0
  70. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/delete.py +0 -0
  71. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/extract.py +0 -0
  72. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/fetch_templates.py +0 -0
  73. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/list.py +0 -0
  74. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/list_tags.py +0 -0
  75. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/load.py +0 -0
  76. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/prompt.py +0 -0
  77. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/read.py +0 -0
  78. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/read_status.py +0 -0
  79. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/read_user.py +0 -0
  80. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/reconnect.py +0 -0
  81. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/rename.py +0 -0
  82. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/scan.py +0 -0
  83. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/set_status.py +0 -0
  84. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/set_user.py +0 -0
  85. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/ara_subcommands/template.py +0 -0
  86. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_creator.py +0 -0
  87. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_deleter.py +0 -0
  88. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_fuzzy_search.py +0 -0
  89. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_link_updater.py +0 -0
  90. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_lister.py +0 -0
  91. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/__init__.py +0 -0
  92. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/artefact_data_retrieval.py +0 -0
  93. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/artefact_load.py +0 -0
  94. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/artefact_mapping.py +0 -0
  95. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/businessgoal_artefact_model.py +0 -0
  96. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/capability_artefact_model.py +0 -0
  97. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/example_artefact_model.py +0 -0
  98. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/issue_artefact_model.py +0 -0
  99. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/keyfeature_artefact_model.py +0 -0
  100. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/serialize_helper.py +0 -0
  101. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/task_artefact_model.py +0 -0
  102. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_models/vision_artefact_model.py +0 -0
  103. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_reader.py +0 -0
  104. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_renamer.py +0 -0
  105. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/artefact_scan.py +0 -0
  106. {ara_cli-0.1.10.1/ara_cli/commands → ara_cli-0.1.10.8/ara_cli/chat_agent}/__init__.py +0 -0
  107. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/classifier.py +0 -0
  108. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/codefusionretriever.py +0 -0
  109. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/codehierachieretriever.py +0 -0
  110. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/commandline_completer.py +0 -0
  111. {ara_cli-0.1.10.1/ara_cli/file_loaders → ara_cli-0.1.10.8/ara_cli/commands}/__init__.py +0 -0
  112. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/commands/command.py +0 -0
  113. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/commands/extract_command.py +0 -0
  114. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/commands/load_command.py +0 -0
  115. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/commands/load_image_command.py +0 -0
  116. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/commands/read_command.py +0 -0
  117. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/completers.py +0 -0
  118. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/error_handler.py +0 -0
  119. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_classifier.py +0 -0
  120. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_lister.py +0 -0
  121. {ara_cli-0.1.10.1/tests → ara_cli-0.1.10.8/ara_cli/file_loaders}/__init__.py +0 -0
  122. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/binary_file_loader.py +0 -0
  123. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/document_file_loader.py +0 -0
  124. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/document_reader.py +0 -0
  125. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/document_readers.py +0 -0
  126. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/file_loader.py +0 -0
  127. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/file_loaders.py +0 -0
  128. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/image_processor.py +0 -0
  129. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/file_loaders/markdown_reader.py +0 -0
  130. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/filename_validator.py +0 -0
  131. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/list_filter.py +0 -0
  132. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/output_suppressor.py +0 -0
  133. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/prompt_chat.py +0 -0
  134. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/prompt_rag.py +0 -0
  135. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/run_file_lister.py +0 -0
  136. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/template_manager.py +0 -0
  137. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/agile.artefacts +0 -0
  138. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/blueprints/empty.blueprint.md +0 -0
  139. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_C4_architecture_analysis.blueprint.md +0 -0
  140. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/commands/architecture_C4_analysis.commands.md +0 -0
  141. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/commands/architecture_radon_cc_score.commands.md +0 -0
  142. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/commands/architecture_radon_halstead_v.commands.md +0 -0
  143. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/commands/architecture_radon_maintainability_score.commands.md +0 -0
  144. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/classify_task.intention.md +0 -0
  145. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/empty.intention.md +0 -0
  146. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/error_fixing.intention.md +0 -0
  147. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/feature_fix_steps_for_scenario.intention.md +0 -0
  148. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/feature_formulation.intention.md +0 -0
  149. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/feature_reverse_formulation_from_code.intention.md +0 -0
  150. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation.intention.md +0 -0
  151. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation_update.intention.md +0 -0
  152. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/feature_scenario_outline_extension.intention.md +0 -0
  153. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/feature_update_formulation.intention.md +0 -0
  154. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/fibonacci_example_implementation.intention.md +0 -0
  155. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/js_implementation_from_task_description.intention.md +0 -0
  156. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/js_steps_implementation.intention.md +0 -0
  157. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/python_cli_implementation_with_test.intention.md +0 -0
  158. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/python_code_understanding.intention.md +0 -0
  159. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/task_implementation.intention.md +0 -0
  160. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/task_prompt_control_by_status.intention.md +0 -0
  161. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_number.intention.md +0 -0
  162. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_status.intention.md +0 -0
  163. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/architecture_analyst.rules.md +0 -0
  164. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/code_analyst.rules.md +0 -0
  165. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/empty.rules.md +0 -0
  166. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/error_analyst.rules.md +0 -0
  167. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/gherkin_expert.rules.md +0 -0
  168. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/js_expert_developer.rules.md +0 -0
  169. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/product_owner.rules.md +0 -0
  170. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/python_behave.rules.md +0 -0
  171. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/prompt-modules/rules/python_developer.rules.md +0 -0
  172. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.concept.exploration.md +0 -0
  173. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.concept.md +0 -0
  174. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.customer.exploration.md +0 -0
  175. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.customer.md +0 -0
  176. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.persona.exploration.md +0 -0
  177. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.persona.md +0 -0
  178. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.step.exploration.md +0 -0
  179. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.step.md +0 -0
  180. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.technology.exploration.md +0 -0
  181. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/specification_breakdown_files/template.technology.md +0 -0
  182. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.businessgoal.prompt_log.md +0 -0
  183. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.capability.prompt_log.md +0 -0
  184. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.epic.prompt_log.md +0 -0
  185. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.example.prompt_log.md +0 -0
  186. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.feature.prompt_log.md +0 -0
  187. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.issue.prompt_log.md +0 -0
  188. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.keyfeature.prompt_log.md +0 -0
  189. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.steps.prompt_log.md +0 -0
  190. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.task.prompt_log.md +0 -0
  191. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.userstory.prompt_log.md +0 -0
  192. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/templates/template.vision.prompt_log.md +0 -0
  193. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli/update_config_prompt.py +0 -0
  194. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli.egg-info/dependency_links.txt +0 -0
  195. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli.egg-info/entry_points.txt +0 -0
  196. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/ara_cli.egg-info/top_level.txt +0 -0
  197. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/setup.cfg +0 -0
  198. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/setup.py +0 -0
  199. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_ara_command_action.py +0 -0
  200. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_ara_config.py +0 -0
  201. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_artefact_autofix.py +0 -0
  202. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_artefact_fuzzy_search.py +0 -0
  203. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_artefact_link_updater.py +0 -0
  204. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_artefact_lister.py +0 -0
  205. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_artefact_reader.py +0 -0
  206. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_artefact_renamer.py +0 -0
  207. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_artefact_scan.py +0 -0
  208. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_chat.py +0 -0
  209. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_classifier.py +0 -0
  210. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_directory_navigator.py +0 -0
  211. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_file_classifier.py +0 -0
  212. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_file_creator.py +0 -0
  213. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_file_lister.py +0 -0
  214. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_list_filter.py +0 -0
  215. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_tag_extractor.py +0 -0
  216. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_template_loader.py +0 -0
  217. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_template_manager.py +0 -0
  218. {ara_cli-0.1.10.1 → ara_cli-0.1.10.8}/tests/test_update_config_prompt.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ara_cli
3
- Version: 0.1.10.1
3
+ Version: 0.1.10.8
4
4
  Summary: Powerful, open source command-line tool for managing, structuring and automating software development artifacts in line with Business-Driven Development (BDD) and AI-assisted processes
5
5
  Description-Content-Type: text/markdown
6
6
  Requires-Dist: langfuse
@@ -20,6 +20,7 @@ Requires-Dist: pydantic_ai
20
20
  Requires-Dist: python-docx
21
21
  Requires-Dist: pymupdf4llm
22
22
  Requires-Dist: typer
23
+ Requires-Dist: psutil
23
24
  Dynamic: description
24
25
  Dynamic: description-content-type
25
26
  Dynamic: requires-dist
@@ -130,6 +131,35 @@ ara autofix
130
131
 
131
132
  See `ara -h` for the complete list of commands and usage examples.
132
133
 
134
+ ---
135
+ ## Agent Commands
136
+
137
+ `ara-cli` includes powerful agent-based capabilities that can be accessed through the interactive chat. These agents can perform complex, multi-step tasks, such as conducting interviews or automating coding workflows.
138
+
139
+ To use the agent commands, first start an interactive chat session:
140
+
141
+ ```bash
142
+ ara prompt chat <artefact_classifier> <artefact_name>
143
+ ```
144
+
145
+ Once inside the chat, you can use the following commands to manage agents:
146
+
147
+ | Command | Shortcut | Description |
148
+ | ---------------- | -------- | ------------------------------------------------- |
149
+ | `AGENT_RUN` | `a` | Run an agent by name. |
150
+ | `AGENT_STOP` | `as` | Stop the currently running agent. |
151
+ | `AGENT_CONTINUE` | `ac` | Continue the agent's operation without new input. |
152
+ | `AGENT_STATUS` | `astat` | Show the status of the current agent. |
153
+ | `exit` | | Exit from agent interfacto back to chat. |
154
+
155
+ **Example:**
156
+
157
+ ```bash
158
+ ara> a interview_agent
159
+ ```
160
+
161
+ **Important:** The agent functionality requires the `ara-agents` package to be installed separately. If you do not have `ara-agents` installed, please contact the Talsen Team for assistance.
162
+
133
163
  ---
134
164
 
135
165
  ## Artefact Structure
@@ -103,6 +103,35 @@ ara autofix
103
103
 
104
104
  See `ara -h` for the complete list of commands and usage examples.
105
105
 
106
+ ---
107
+ ## Agent Commands
108
+
109
+ `ara-cli` includes powerful agent-based capabilities that can be accessed through the interactive chat. These agents can perform complex, multi-step tasks, such as conducting interviews or automating coding workflows.
110
+
111
+ To use the agent commands, first start an interactive chat session:
112
+
113
+ ```bash
114
+ ara prompt chat <artefact_classifier> <artefact_name>
115
+ ```
116
+
117
+ Once inside the chat, you can use the following commands to manage agents:
118
+
119
+ | Command | Shortcut | Description |
120
+ | ---------------- | -------- | ------------------------------------------------- |
121
+ | `AGENT_RUN` | `a` | Run an agent by name. |
122
+ | `AGENT_STOP` | `as` | Stop the currently running agent. |
123
+ | `AGENT_CONTINUE` | `ac` | Continue the agent's operation without new input. |
124
+ | `AGENT_STATUS` | `astat` | Show the status of the current agent. |
125
+ | `exit` | | Exit from agent interfacto back to chat. |
126
+
127
+ **Example:**
128
+
129
+ ```bash
130
+ ara> a interview_agent
131
+ ```
132
+
133
+ **Important:** The agent functionality requires the `ara-agents` package to be installed separately. If you do not have `ara-agents` installed, please contact the Talsen Team for assistance.
134
+
106
135
  ---
107
136
 
108
137
  ## Artefact Structure
@@ -4,7 +4,6 @@ from .error_handler import ErrorHandler
4
4
 
5
5
  whitelisted_commands = ["RERUN", "SEND", "EXTRACT", "LOAD_IMAGE", "CHOOSE_MODEL", "CHOOSE_EXTRACTION_MODEL", "CURRENT_MODEL", "CURRENT_EXTRACTION_MODEL", "LIST_MODELS"]
6
6
 
7
-
8
7
  error_handler = ErrorHandler()
9
8
 
10
9
 
@@ -1,8 +1,7 @@
1
1
  import typer
2
- import sys
2
+ import os
3
3
  from typing import Optional
4
4
  from os import getenv
5
- from ara_cli.error_handler import AraError
6
5
  from ara_cli.version import __version__
7
6
  from ara_cli import error_handler
8
7
  from ara_cli.ara_subcommands.create import register as register_create_cli
@@ -26,6 +25,8 @@ from ara_cli.ara_subcommands.autofix import register as register_autofix_cli
26
25
  from ara_cli.ara_subcommands.extract import register as register_extract_cli
27
26
  from ara_cli.ara_subcommands.load import register as register_load_cli
28
27
 
28
+ from ara_cli.directory_navigator import DirectoryNavigator
29
+
29
30
 
30
31
  def version_callback(value: bool):
31
32
  if value:
@@ -44,6 +45,87 @@ def configure_debug_mode(debug: bool, env_debug_mode: bool):
44
45
  error_handler.debug_mode = True
45
46
 
46
47
 
48
+ def check_ara_directory_exists():
49
+ """Check if ara directory exists or if we're inside ara directory tree."""
50
+ return DirectoryNavigator.find_ara_directory_root() is not None
51
+
52
+
53
+ def prompt_create_ara_directory():
54
+ """Prompt user to create ara directory and create it if confirmed."""
55
+ # Print the prompt message
56
+ print("No 'ara' directory found. Create one in the current directory? (Y/n)",
57
+ end=" ", flush=True)
58
+
59
+ # Read user input
60
+ try:
61
+ response = input().strip()
62
+ except (EOFError, KeyboardInterrupt):
63
+ typer.echo("\nOperation cancelled.")
64
+ raise typer.Exit(1)
65
+
66
+ if response.lower() in ('y', 'yes', ''):
67
+ current_dir = os.getcwd()
68
+ ara_path = os.path.join(current_dir, 'ara')
69
+
70
+ # Create ara directory structure
71
+ subdirectories = [
72
+ 'businessgoals',
73
+ 'capabilities',
74
+ 'epics',
75
+ 'examples',
76
+ 'features',
77
+ 'keyfeatures',
78
+ 'tasks',
79
+ 'userstories',
80
+ 'vision'
81
+ ]
82
+
83
+ try:
84
+ # Create main ara directory
85
+ os.makedirs(ara_path, exist_ok=True)
86
+
87
+ # Create subdirectories for artefact types
88
+ for subdir in subdirectories:
89
+ os.makedirs(os.path.join(ara_path, subdir), exist_ok=True)
90
+
91
+ # Create .araconfig directory
92
+ araconfig_path = os.path.join(ara_path, '.araconfig')
93
+ os.makedirs(araconfig_path, exist_ok=True)
94
+
95
+ # Create default ara_config.json using ConfigManager
96
+ from ara_cli.ara_config import ConfigManager, ARAconfig
97
+ config_file_path = os.path.join(araconfig_path, 'ara_config.json')
98
+
99
+ # Reset ConfigManager to ensure clean state
100
+ ConfigManager.reset()
101
+
102
+ # Create default config and save it
103
+ default_config = ARAconfig()
104
+ from ara_cli.ara_config import save_data
105
+ save_data(config_file_path, default_config)
106
+
107
+ typer.echo(f"Created ara directory structure at {ara_path}")
108
+ typer.echo(f"Created default configuration at {config_file_path}")
109
+ return True
110
+
111
+ except OSError as e:
112
+ typer.echo(f"Error creating ara directory: {e}", err=True)
113
+ raise typer.Exit(1)
114
+ except Exception as e:
115
+ typer.echo(f"Error creating configuration file: {e}", err=True)
116
+ raise typer.Exit(1)
117
+ else:
118
+ typer.echo("Ara directory creation cancelled.")
119
+ raise typer.Exit(0)
120
+
121
+
122
+ def requires_ara_directory():
123
+ """Check if ara directory exists and prompt to create if not."""
124
+ if not check_ara_directory_exists():
125
+ return prompt_create_ara_directory()
126
+ return True
127
+
128
+
47
129
  def create_app():
48
130
  app = typer.Typer(
49
131
  help="""The ara cli terminal tool is a management tool for classified ara artefacts.
@@ -125,6 +207,17 @@ ara chat examples:
125
207
  ctx.get_help()
126
208
  ctx.exit()
127
209
 
210
+ # Check for ara directory before executing any command
211
+ # Skip check for commands that don't require ara directory
212
+ commands_requiring_ara = {
213
+ 'create', 'delete', 'rename', 'list', 'list-tags', 'prompt',
214
+ 'read', 'reconnect', 'read-status', 'read-user', 'set-status',
215
+ 'set-user', 'classifier-directory', 'scan', 'autofix'
216
+ }
217
+
218
+ if ctx.invoked_subcommand in commands_requiring_ara:
219
+ requires_ara_directory()
220
+
128
221
  # Register all commands
129
222
  register_create_cli(app)
130
223
  register_delete_cli(app)
@@ -487,7 +487,7 @@ def _convert_to_scenario_outline(scenario_lines: list, placeholders: set, indent
487
487
  def _create_examples_table(placeholders: set, base_indentation: str) -> list:
488
488
  """Create the Examples table for the scenario outline."""
489
489
  examples_indentation = base_indentation + " "
490
- table_indentation = examples_indentation + " "
490
+ table_indentation = examples_indentation + " "
491
491
 
492
492
  sorted_placeholders = sorted(placeholders)
493
493
  header = "| " + " | ".join(sorted_placeholders) + " |"
@@ -576,6 +576,42 @@ def fix_rule(
576
576
  return artefact.serialize()
577
577
 
578
578
 
579
+ def fix_misplaced_content(file_path: str, artefact_text: str, **kwargs) -> str:
580
+ """
581
+ Deterministically fixes content like 'Rule:' or 'Estimate:' misplaced in the description.
582
+ """
583
+ lines = artefact_text.splitlines()
584
+
585
+ desc_start_idx = -1
586
+ for i, line in enumerate(lines):
587
+ if line.strip().startswith("Description:"):
588
+ desc_start_idx = i
589
+ break
590
+
591
+ if desc_start_idx == -1:
592
+ return artefact_text # No description, nothing to fix.
593
+
594
+ pre_desc_lines = lines[:desc_start_idx]
595
+ desc_line = lines[desc_start_idx]
596
+ post_desc_lines = lines[desc_start_idx+1:]
597
+
598
+ misplaced_content = []
599
+ new_post_desc_lines = []
600
+
601
+ for line in post_desc_lines:
602
+ if line.strip().startswith("Rule:") or line.strip().startswith("Estimate:"):
603
+ misplaced_content.append(line)
604
+ else:
605
+ new_post_desc_lines.append(line)
606
+
607
+ if not misplaced_content:
608
+ return artefact_text
609
+
610
+ # Rebuild the file content
611
+ final_lines = pre_desc_lines + misplaced_content + [""] + [desc_line] + new_post_desc_lines
612
+ return "\n".join(final_lines)
613
+
614
+
579
615
  def should_skip_issue(deterministic_issue, deterministic, non_deterministic, file_path) -> bool:
580
616
  if not non_deterministic and not deterministic_issue:
581
617
  print(f"Skipping non-deterministic fix for {file_path} as per request.")
@@ -622,7 +658,7 @@ def apply_non_deterministic_fix(
622
658
  corrected_artefact = run_agent(prompt, artefact_class)
623
659
  corrected_text = corrected_artefact.serialize()
624
660
  except Exception as e:
625
- print(f" ❌ LLM agent failed to fix artefact at {file_path}: {e}")
661
+ print(f" ❌ LLM agent failed to fix artefact at {file_path}: {e}")
626
662
  return None
627
663
  return corrected_text
628
664
 
@@ -651,7 +687,7 @@ def attempt_autofix_loop(
651
687
  print(
652
688
  f"Attempting to fix {file_path} (Attempt {attempt + 1}/{max_attempts})..."
653
689
  )
654
- print(f" Reason: {current_reason}")
690
+ print(f" Reason: {current_reason}")
655
691
 
656
692
  artefact_text = read_artefact(file_path)
657
693
  if artefact_text is None:
@@ -683,13 +719,13 @@ def attempt_autofix_loop(
683
719
 
684
720
  if corrected_text is None or corrected_text.strip() == artefact_text.strip():
685
721
  print(
686
- " Fixing attempt did not alter the file. Stopping to prevent infinite loop."
722
+ " Fixing attempt did not alter the file. Stopping to prevent infinite loop."
687
723
  )
688
724
  return False
689
725
 
690
726
  write_corrected_artefact(file_path, corrected_text)
691
727
 
692
- print(" File modified. Re-classifying artefact information for next check...")
728
+ print(" File modified. Re-classifying artefact information for next check...")
693
729
  classified_artefact_info = populate_classified_artefact_info(classified_artefact_info, force=True)
694
730
 
695
731
  print(f"❌ Failed to fix {file_path} after {max_attempts} attempts.")
@@ -713,6 +749,8 @@ def apply_autofix(
713
749
  "Invalid Contribution Reference": fix_contribution,
714
750
  "Rule Mismatch": fix_rule,
715
751
  "Scenario Contains Placeholders": fix_scenario_placeholder_mismatch,
752
+ "Found 'Rule:' inside description": fix_misplaced_content,
753
+ "Found 'Estimate:' inside description": fix_misplaced_content,
716
754
  }
717
755
 
718
756
  artefact_type, artefact_class = determine_artefact_type_and_class(classifier)
@@ -731,4 +769,4 @@ def apply_autofix(
731
769
  deterministic=deterministic,
732
770
  non_deterministic=non_deterministic,
733
771
  classified_artefact_info=classified_artefact_info,
734
- )
772
+ )
@@ -410,14 +410,26 @@ class Artefact(BaseModel, ABC):
410
410
  return contribution, lines
411
411
 
412
412
  @classmethod
413
- def _deserialize_description(cls, lines) -> (Optional[str], List[str]):
413
+ def _deserialize_description(cls, lines: List[str]) -> (Optional[str], List[str]):
414
414
  description_start = cls._description_starts_with()
415
+ start_index = -1
415
416
  for i, line in enumerate(lines):
416
417
  if line.startswith(description_start):
417
- description = line[len(description_start):].strip()
418
- del lines[i]
419
- return description, lines
420
- return None, lines
418
+ start_index = i
419
+ break
420
+
421
+ if start_index == -1:
422
+ return None, lines
423
+
424
+ first_line_content = lines[start_index][len(description_start):].strip()
425
+
426
+ description_lines = ([first_line_content] if first_line_content else []) + lines[start_index + 1:]
427
+
428
+ description = "\n".join(description_lines)
429
+
430
+ remaining_lines = lines[:start_index]
431
+
432
+ return (description if description else None), remaining_lines
421
433
 
422
434
  @classmethod
423
435
  def _parse_common_fields(cls, text: str) -> dict:
@@ -499,4 +511,4 @@ class Artefact(BaseModel, ABC):
499
511
  classifier=classifier,
500
512
  rule=rule
501
513
  )
502
- self.contribution = contribution
514
+ self.contribution = contribution
@@ -204,7 +204,8 @@ def _default_feature(title: str, use_default_contribution: bool) -> FeatureArtef
204
204
 
205
205
  def _default_task(title: str, use_default_contribution: bool) -> TaskArtefact:
206
206
  return TaskArtefact(
207
- status="to-do",
207
+ tags=[],
208
+ status=None,
208
209
  title=title,
209
210
  description="<further optional description to understand the task, no format defined>",
210
211
  contribution=default_contribution() if use_default_contribution else None
@@ -1,5 +1,5 @@
1
1
  from ara_cli.artefact_models.artefact_model import Artefact, ArtefactType, Intent
2
- from pydantic import Field, field_validator
2
+ from pydantic import Field, field_validator, model_validator
3
3
  from typing import List, Tuple, Optional
4
4
 
5
5
 
@@ -91,6 +91,15 @@ class EpicArtefact(Artefact):
91
91
  description="Rules the epic defines. It is recommended to create rules to clarify the desired outcome"
92
92
  )
93
93
 
94
+ @model_validator(mode='after')
95
+ def check_for_misplaced_rules(self) -> 'EpicArtefact':
96
+ if self.description:
97
+ desc_lines = self.description.split('\n')
98
+ for line in desc_lines:
99
+ if line.strip().startswith("Rule:"):
100
+ raise ValueError("Found 'Rule:' inside description. Rules must be defined before the 'Description:' section.")
101
+ return self
102
+
94
103
  @field_validator('artefact_type')
95
104
  def validate_artefact_type(cls, v):
96
105
  if v != ArtefactType.epic:
@@ -166,4 +175,4 @@ class EpicArtefact(Artefact):
166
175
  lines.append("")
167
176
  lines.append(description)
168
177
  lines.append("")
169
- return "\n".join(lines)
178
+ return "\n".join(lines)
@@ -301,6 +301,36 @@ class FeatureArtefact(Artefact):
301
301
  f"FeatureArtefact must have artefact_type of '{ArtefactType.feature}', not '{v}'")
302
302
  return v
303
303
 
304
+ @classmethod
305
+ def _deserialize_description(cls, lines: List[str]) -> (Optional[str], List[str]):
306
+ description_start = cls._description_starts_with()
307
+ scenario_markers = ["Scenario:", "Scenario Outline:"]
308
+
309
+ start_index = -1
310
+ for i, line in enumerate(lines):
311
+ if line.startswith(description_start):
312
+ start_index = i
313
+ break
314
+
315
+ if start_index == -1:
316
+ return None, lines
317
+
318
+ end_index = len(lines)
319
+ for i in range(start_index + 1, len(lines)):
320
+ if any(lines[i].startswith(marker) for marker in scenario_markers):
321
+ end_index = i
322
+ break
323
+
324
+ first_line_content = lines[start_index][len(description_start):].strip()
325
+
326
+ description_lines_list = [first_line_content] if first_line_content else []
327
+ description_lines_list.extend(lines[start_index+1:end_index])
328
+
329
+ description = "\n".join(description_lines_list).strip() or None
330
+
331
+ remaining_lines = lines[:start_index] + lines[end_index:]
332
+
333
+ return description, remaining_lines
304
334
 
305
335
  @classmethod
306
336
  def _title_prefix(cls) -> str:
@@ -519,4 +549,4 @@ class FeatureArtefact(Artefact):
519
549
  # or the placeholder is at the end of a line (e.g., "Then I see... __PLACEHOLDER__").
520
550
  step = step.replace(key, value)
521
551
  rehydrated_steps.append(step)
522
- return rehydrated_steps
552
+ return rehydrated_steps
@@ -1,5 +1,5 @@
1
1
  from ara_cli.artefact_models.artefact_model import Artefact, ArtefactType, Intent
2
- from pydantic import Field, field_validator
2
+ from pydantic import Field, field_validator, model_validator
3
3
  from typing import List, Tuple
4
4
 
5
5
 
@@ -92,6 +92,18 @@ class UserstoryArtefact(Artefact):
92
92
  default_factory=list,
93
93
  description="Rules the userstory defines. It is recommended to create rules to clarify the desired outcome")
94
94
 
95
+ @model_validator(mode='after')
96
+ def check_for_misplaced_content(self) -> 'UserstoryArtefact':
97
+ if self.description:
98
+ desc_lines = self.description.split('\n')
99
+ for line in desc_lines:
100
+ stripped_line = line.strip()
101
+ if stripped_line.startswith("Rule:"):
102
+ raise ValueError("Found 'Rule:' inside description. Rules must be defined before the 'Description:' section.")
103
+ if stripped_line.startswith("Estimate:"):
104
+ raise ValueError("Found 'Estimate:' inside description. Estimate must be defined before the 'Description:' section.")
105
+ return self
106
+
95
107
  @field_validator('artefact_type')
96
108
  def validate_artefact_type(cls, v):
97
109
  if v != ArtefactType.userstory: