ara-cli 0.1.9.62__tar.gz → 0.1.9.64__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 (164) hide show
  1. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/PKG-INFO +1 -1
  2. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/ara_command_action.py +16 -2
  3. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/ara_command_parser.py +2 -0
  4. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_autofix.py +19 -8
  5. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_fuzzy_search.py +21 -2
  6. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/artefact_model.py +1 -1
  7. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/businessgoal_artefact_model.py +6 -1
  8. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/epic_artefact_model.py +6 -1
  9. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/feature_artefact_model.py +72 -4
  10. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/keyfeature_artefact_model.py +6 -1
  11. ara_cli-0.1.9.64/ara_cli/artefact_models/serialize_helper.py +18 -0
  12. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/userstory_artefact_model.py +6 -1
  13. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_scan.py +2 -0
  14. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/prompt_extractor.py +7 -3
  15. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/prompt_handler.py +20 -7
  16. ara_cli-0.1.9.64/ara_cli/tag_extractor.py +56 -0
  17. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/version.py +1 -1
  18. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli.egg-info/PKG-INFO +1 -1
  19. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli.egg-info/SOURCES.txt +1 -0
  20. ara_cli-0.1.9.62/ara_cli/tag_extractor.py +0 -31
  21. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/MANIFEST.in +0 -0
  22. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/README.md +0 -0
  23. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/__init__.py +0 -0
  24. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/__main__.py +0 -0
  25. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/ara_config.py +0 -0
  26. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_creator.py +0 -0
  27. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_deleter.py +0 -0
  28. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_link_updater.py +0 -0
  29. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_lister.py +0 -0
  30. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/artefact_load.py +0 -0
  31. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/artefact_mapping.py +0 -0
  32. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/artefact_templates.py +0 -0
  33. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/capability_artefact_model.py +0 -0
  34. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/example_artefact_model.py +0 -0
  35. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/issue_artefact_model.py +0 -0
  36. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/task_artefact_model.py +0 -0
  37. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_models/vision_artefact_model.py +0 -0
  38. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_reader.py +0 -0
  39. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/artefact_renamer.py +0 -0
  40. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/chat.py +0 -0
  41. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/classifier.py +0 -0
  42. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/codefusionretriever.py +0 -0
  43. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/codehierachieretriever.py +0 -0
  44. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/commandline_completer.py +0 -0
  45. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/directory_navigator.py +0 -0
  46. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/file_classifier.py +0 -0
  47. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/file_lister.py +0 -0
  48. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/filename_validator.py +0 -0
  49. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/list_filter.py +0 -0
  50. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/output_suppressor.py +0 -0
  51. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/prompt_chat.py +0 -0
  52. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/prompt_rag.py +0 -0
  53. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/run_file_lister.py +0 -0
  54. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/template_manager.py +0 -0
  55. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/agile.artefacts +0 -0
  56. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -0
  57. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/blueprints/empty.blueprint.md +0 -0
  58. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_C4_architecture_analysis.blueprint.md +0 -0
  59. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -0
  60. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/architecture_C4_analysis.commands.md +0 -0
  61. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/architecture_radon_cc_score.commands.md +0 -0
  62. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/architecture_radon_halstead_v.commands.md +0 -0
  63. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/architecture_radon_maintainability_score.commands.md +0 -0
  64. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -0
  65. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -0
  66. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -0
  67. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -0
  68. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -0
  69. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -0
  70. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/empty.commands.md +0 -0
  71. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -0
  72. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -0
  73. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -0
  74. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -0
  75. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -0
  76. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -0
  77. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -0
  78. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -0
  79. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/classify_task.intention.md +0 -0
  80. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/empty.intention.md +0 -0
  81. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/error_fixing.intention.md +0 -0
  82. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/feature_fix_steps_for_scenario.intention.md +0 -0
  83. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/feature_formulation.intention.md +0 -0
  84. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/feature_reverse_formulation_from_code.intention.md +0 -0
  85. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation.intention.md +0 -0
  86. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation_update.intention.md +0 -0
  87. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/feature_scenario_outline_extension.intention.md +0 -0
  88. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/feature_update_formulation.intention.md +0 -0
  89. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/fibonacci_example_implementation.intention.md +0 -0
  90. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/js_implementation_from_task_description.intention.md +0 -0
  91. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/js_steps_implementation.intention.md +0 -0
  92. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/python_cli_implementation_with_test.intention.md +0 -0
  93. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/python_code_understanding.intention.md +0 -0
  94. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/task_implementation.intention.md +0 -0
  95. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/task_prompt_control_by_status.intention.md +0 -0
  96. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_number.intention.md +0 -0
  97. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_status.intention.md +0 -0
  98. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/architecture_analyst.rules.md +0 -0
  99. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/code_analyst.rules.md +0 -0
  100. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/empty.rules.md +0 -0
  101. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/error_analyst.rules.md +0 -0
  102. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/gherkin_expert.rules.md +0 -0
  103. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/js_expert_developer.rules.md +0 -0
  104. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/product_owner.rules.md +0 -0
  105. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/python_behave.rules.md +0 -0
  106. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/prompt-modules/rules/python_developer.rules.md +0 -0
  107. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.concept.exploration.md +0 -0
  108. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.concept.md +0 -0
  109. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.customer.exploration.md +0 -0
  110. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.customer.md +0 -0
  111. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.persona.exploration.md +0 -0
  112. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.persona.md +0 -0
  113. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.step.exploration.md +0 -0
  114. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.step.md +0 -0
  115. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.technology.exploration.md +0 -0
  116. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/specification_breakdown_files/template.technology.md +0 -0
  117. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.businessgoal +0 -0
  118. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.businessgoal.prompt_log.md +0 -0
  119. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.capability +0 -0
  120. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.capability.prompt_log.md +0 -0
  121. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.epic +0 -0
  122. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.epic.prompt_log.md +0 -0
  123. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.example +0 -0
  124. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.example.prompt_log.md +0 -0
  125. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.feature +0 -0
  126. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.feature.prompt_log.md +0 -0
  127. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.issue +0 -0
  128. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.issue.prompt_log.md +0 -0
  129. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.keyfeature +0 -0
  130. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.keyfeature.prompt_log.md +0 -0
  131. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.steps.prompt_log.md +0 -0
  132. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.task +0 -0
  133. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.task.prompt_log.md +0 -0
  134. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.userstory +0 -0
  135. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.userstory.prompt_log.md +0 -0
  136. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.vision +0 -0
  137. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/templates/template.vision.prompt_log.md +0 -0
  138. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/__init__.py +0 -0
  139. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_ara_autofix.py +0 -0
  140. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_ara_command_action.py +0 -0
  141. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_ara_config.py +0 -0
  142. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_artefact_fuzzy_search.py +0 -0
  143. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_artefact_link_updater.py +0 -0
  144. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_artefact_lister.py +0 -0
  145. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_artefact_reader.py +0 -0
  146. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_artefact_renamer.py +0 -0
  147. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_artefact_scan.py +0 -0
  148. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_chat.py +0 -0
  149. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_classifier.py +0 -0
  150. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_directory_navigator.py +0 -0
  151. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_file_classifier.py +0 -0
  152. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_file_creator.py +0 -0
  153. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_file_lister.py +0 -0
  154. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_list_filter.py +0 -0
  155. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_tag_extractor.py +0 -0
  156. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_template_manager.py +0 -0
  157. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/tests/test_update_config_prompt.py +0 -0
  158. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli/update_config_prompt.py +0 -0
  159. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli.egg-info/dependency_links.txt +0 -0
  160. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli.egg-info/entry_points.txt +0 -0
  161. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli.egg-info/requires.txt +0 -0
  162. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/ara_cli.egg-info/top_level.txt +0 -0
  163. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/setup.cfg +0 -0
  164. {ara_cli-0.1.9.62 → ara_cli-0.1.9.64}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ara_cli
3
- Version: 0.1.9.62
3
+ Version: 0.1.9.64
4
4
  Requires-Dist: litellm
5
5
  Requires-Dist: llama-index
6
6
  Requires-Dist: llama-index-llms-openai
@@ -128,7 +128,10 @@ def list_tags_action(args):
128
128
  tag_classifier = args.include_classifier
129
129
 
130
130
  tag_extractor = TagExtractor()
131
- tags = tag_extractor.extract_tags(include_classifier=tag_classifier)
131
+ tags = tag_extractor.extract_tags(
132
+ include_classifier=tag_classifier,
133
+ filtered_extra_column=getattr(args, "filtered_extra_column", False)
134
+ )
132
135
 
133
136
  if args.json:
134
137
  output = json.dumps({"tags": tags})
@@ -331,11 +334,15 @@ def reconnect_action(args):
331
334
  from ara_cli.artefact_models.artefact_load import artefact_from_content
332
335
  from ara_cli.artefact_models.artefact_model import Contribution
333
336
  from ara_cli.artefact_reader import ArtefactReader
337
+ from ara_cli.artefact_fuzzy_search import find_closest_rule
334
338
 
335
339
  classifier = args.classifier
336
340
  artefact_name = args.parameter
337
341
  parent_classifier = args.parent_classifier
338
342
  parent_name = args.parent_name
343
+ rule = None
344
+ if args.rule:
345
+ rule = ' '.join(args.rule)
339
346
 
340
347
  read_error_message = f"Could not connect {classifier} '{artefact_name}' to {parent_classifier} '{parent_name}'"
341
348
 
@@ -364,10 +371,17 @@ def reconnect_action(args):
364
371
  content=parent_content
365
372
  )
366
373
 
367
- artefact.contribution = Contribution(
374
+ contribution = Contribution(
368
375
  artefact_name=parent.title,
369
376
  classifier=parent.artefact_type
370
377
  )
378
+
379
+ if rule:
380
+ closest_rule = find_closest_rule(parent, rule)
381
+ print("")
382
+ contribution.rule = closest_rule
383
+
384
+ artefact.contribution = contribution
371
385
  with open(artefact.file_path, 'w') as file:
372
386
  artefact_content = artefact.serialize()
373
387
  file.write(artefact_content)
@@ -121,6 +121,7 @@ def list_tags_parser(subparsers):
121
121
  tags_parser = subparsers.add_parser("list-tags", help="Show tags")
122
122
  tags_parser.add_argument("--json", "-j", help="Output tags as JSON", action=argparse.BooleanOptionalAction)
123
123
  tags_parser.add_argument("--include-classifier", choices=classifiers, help="Show tags for an artefact type")
124
+ tags_parser.add_argument("--filtered-extra-column", action="store_true", help="Filter tags for extra column")
124
125
 
125
126
 
126
127
  def add_chat_arguments(chat_parser):
@@ -183,6 +184,7 @@ def reconnect_parser(subparsers):
183
184
  reconnect_parser.add_argument("parameter", help="Filename of artefact").completer = ArtefactCompleter()
184
185
  reconnect_parser.add_argument("parent_classifier", choices=classifiers, help="Classifier of the parent artefact type")
185
186
  reconnect_parser.add_argument("parent_name", help="Filename of parent artefact").completer = ParentNameCompleter()
187
+ reconnect_parser.add_argument("-r", "--rule", dest="rule", nargs='+')
186
188
 
187
189
 
188
190
  def read_status_parser(subparsers):
@@ -83,26 +83,37 @@ def construct_prompt(artefact_type, reason, file_path, artefact_text):
83
83
 
84
84
  prompt = (
85
85
  f"Correct the following {artefact_type} artefact to fix the issue: {reason}. "
86
- f"Provide the complete, corrected artefact. Don't change the artefact's content, "
87
- f"just fix the pydantic model errors. You should follow the name of the file "
88
- f"from its path {file_path} for naming the arteafact's title. The current artefact is:\n{artefact_text}"
86
+ "Provide the corrected artefact. Do not reformulate the artefact, "
87
+ "just fix the pydantic model errors, use correct grammar. "
88
+ "You should follow the name of the file "
89
+ f"from its path {file_path} for naming the arteafact's title. "
90
+ "You are not allowed to use file extention in the artefact title. "
91
+ "You are not allowed to modify, delete or add tags. "
92
+ "User tag should be '@user_<username>'. The pydantic model already provides the '@user_' prefix. "
93
+ "So you should be careful to not make it @user_user_<username>. "
89
94
  )
90
95
 
91
96
  if artefact_type == ArtefactType.task:
92
97
  prompt += (
93
- "\nFor task artefacts, if the action items looks like template or empty "
98
+ "For task artefacts, if the action items looks like template or empty "
94
99
  "then just delete those action items."
95
- "\nFor user tag it should be '@user_{username}'. So you should be careful to "
96
- "not make it @user_user_{username}"
97
100
  )
98
101
 
102
+ prompt += (
103
+ "\nThe current artefact is:\n"
104
+ "```\n"
105
+ f"{artefact_text}\n"
106
+ "```"
107
+ )
108
+
99
109
  return prompt
100
110
 
101
111
 
102
112
  def run_agent(prompt, artefact_class):
103
113
  from pydantic_ai import Agent
104
-
105
- agent = Agent(model="openai:gpt-4o",
114
+ # gpt-4o
115
+ # anthropic:claude-3-7-sonnet-20250219
116
+ agent = Agent(model="anthropic:claude-3-7-sonnet-20250219",
106
117
  result_type=artefact_class, instrument=True)
107
118
  result = agent.run_sync(prompt)
108
119
  return result.data
@@ -1,9 +1,10 @@
1
1
  import difflib
2
+ from textwrap import indent
2
3
  from typing import Optional
3
4
 
4
5
 
5
- def suggest_close_names(artefact_name: str, all_artefact_names: list[str], message: str):
6
- closest_matches = difflib.get_close_matches(artefact_name, all_artefact_names, cutoff=0.5)
6
+ def suggest_close_names(artefact_name: str, all_artefact_names: list[str], message: str, cutoff=0.5):
7
+ closest_matches = difflib.get_close_matches(artefact_name, all_artefact_names, cutoff=cutoff)
7
8
  print(message)
8
9
  if not closest_matches:
9
10
  return
@@ -38,3 +39,21 @@ def find_closest_name_match(artefact_name: str, all_artefact_names: list[str]) -
38
39
  return None
39
40
  closest_match = closest_matches[0]
40
41
  return closest_match
42
+
43
+
44
+ def find_closest_rule(parent_artefact, rule):
45
+ parent_classifier = parent_artefact.artefact_type.value
46
+ parent_title = parent_artefact.title
47
+ if not hasattr(parent_artefact, 'rules'):
48
+ raise TypeError(f"{parent_classifier.capitalize()} artefact '{parent_title}' can not possess rules. Only userstories and epics have rules.")
49
+ rules = parent_artefact.rules
50
+ if rule in rules:
51
+ return rule
52
+ print(f"Rule '{rule}' does not match existing rules in {parent_classifier} artefact '{parent_title}'. Attempting to find closest match among existing rules.")
53
+ closest_matches = difflib.get_close_matches(rule, rules, cutoff=0.5)
54
+ rules_list_string = indent('\n'.join(rules), prefix='\t- ')
55
+ if not closest_matches:
56
+ raise ValueError(f"Can not determine a match for rule '{rule}' in {parent_classifier} artefact '{parent_title}'. Found rules:\n{rules_list_string}")
57
+ closest_match = closest_matches[0]
58
+ print(f"Found closest matching rule of '{closest_match}'")
59
+ return closest_match
@@ -179,7 +179,7 @@ class Artefact(BaseModel, ABC):
179
179
  )
180
180
  description: Optional[str] = Field(
181
181
  default=None,
182
- description="Optional further description to understand the artefact. It is strongly recommended to add a description to every artefact."
182
+ description="Optional further description to understand the artefact. The description should summerize the core intention of the artefact and give additional valuable information about the artefact."
183
183
  )
184
184
 
185
185
  @property
@@ -33,9 +33,14 @@ class BusinessgoalIntent(Intent):
33
33
  return v
34
34
 
35
35
  def serialize(self):
36
+ from ara_cli.artefact_models.serialize_helper import as_a_serializer
37
+
36
38
  lines = []
39
+
40
+ as_a_line = as_a_serializer(self.as_a)
41
+
37
42
  lines.append(f"In order to {self.in_order_to}")
38
- lines.append(f"As a {self.as_a}")
43
+ lines.append(as_a_line)
39
44
  lines.append(f"I want {self.i_want}")
40
45
 
41
46
  return "\n".join(lines)
@@ -34,9 +34,14 @@ class EpicIntent(Intent):
34
34
  return v
35
35
 
36
36
  def serialize(self):
37
+ from ara_cli.artefact_models.serialize_helper import as_a_serializer
38
+
37
39
  lines = []
40
+
41
+ as_a_line = as_a_serializer(self.as_a)
42
+
38
43
  lines.append(f"In order to {self.in_order_to}")
39
- lines.append(f"As a {self.as_a}")
44
+ lines.append(as_a_line)
40
45
  lines.append(f"I want {self.i_want}")
41
46
 
42
47
  return "\n".join(lines)
@@ -1,5 +1,5 @@
1
1
  from pydantic import BaseModel, field_validator, model_validator, Field
2
- from typing import List, Dict, Tuple, Union
2
+ from typing import List, Dict, Tuple, Union, Optional
3
3
  from ara_cli.artefact_models.artefact_model import Artefact, ArtefactType, Intent
4
4
  import re
5
5
 
@@ -34,8 +34,13 @@ class FeatureIntent(Intent):
34
34
  return v
35
35
 
36
36
  def serialize(self):
37
+ from ara_cli.artefact_models.serialize_helper import as_a_serializer
38
+
37
39
  lines = []
38
- lines.append(f"As a {self.as_a}")
40
+
41
+ as_a_line = as_a_serializer(self.as_a)
42
+
43
+ lines.append(as_a_line)
39
44
  lines.append(f"I want to {self.i_want_to}")
40
45
  lines.append(f"So that {self.so_that}")
41
46
 
@@ -59,9 +64,9 @@ class FeatureIntent(Intent):
59
64
  as_a = line[len(as_a_prefix):].strip()
60
65
  if line.startswith(as_a_prefix_alt) and not as_a:
61
66
  as_a = line[len(as_a_prefix_alt):].strip()
62
- elif line.startswith(i_want_to_prefix) and not i_want_to:
67
+ if line.startswith(i_want_to_prefix) and not i_want_to:
63
68
  i_want_to = line[len(i_want_to_prefix):].strip()
64
- elif line.startswith(so_that_prefix) and not so_that:
69
+ if line.startswith(so_that_prefix) and not so_that:
65
70
  so_that = line[len(so_that_prefix):].strip()
66
71
  index += 1
67
72
 
@@ -93,6 +98,35 @@ class Example(BaseModel):
93
98
  return cls(values=values)
94
99
 
95
100
 
101
+ class Background(BaseModel):
102
+ steps: List[str] = Field(
103
+ description="A list of Gherkin 'Given' type steps that describe what the background does."
104
+ )
105
+
106
+ @field_validator('steps', mode='before')
107
+ def validate_steps(cls, v: List[str]) -> List[str]:
108
+ """Ensure steps are non-empty and stripped."""
109
+ steps = [step.strip() for step in v if step.strip()]
110
+ if not steps:
111
+ raise ValueError("steps list must not be empty")
112
+ return steps
113
+
114
+ @classmethod
115
+ def from_lines(cls, lines: List[str], start_idx: int) -> Tuple['Background', int]:
116
+ """Parse a Background from a list of lines starting at start_idx."""
117
+ if not lines[start_idx].startswith('Background:'):
118
+ raise ValueError("Expected 'Background:' at start index")
119
+
120
+ steps = []
121
+ idx = start_idx + 1
122
+ while idx < len(lines) and not lines[idx].startswith('Background:'):
123
+ step = lines[idx].strip()
124
+ if step:
125
+ steps.append(step)
126
+ idx += 1
127
+ return cls(steps=steps), idx
128
+
129
+
96
130
  class Scenario(BaseModel):
97
131
  title: str = Field(
98
132
  description="The name of the scenario, giving a short summary of the test case. It comes from the 'Scenario:' line in the feature file."
@@ -208,6 +242,8 @@ class FeatureArtefact(Artefact):
208
242
  artefact_type: ArtefactType = ArtefactType.feature
209
243
  intent: FeatureIntent
210
244
  scenarios: List[Union[Scenario, ScenarioOutline]] = Field(default=None)
245
+ background: Optional[Background] = Field(
246
+ default=None, description="Highly optional background Gherkin steps for Feature Artefacts. This steps apply for all scenarios and scenario outlines in this feature file.")
211
247
 
212
248
  @field_validator('artefact_type')
213
249
  def validate_artefact_type(cls, v):
@@ -224,6 +260,16 @@ class FeatureArtefact(Artefact):
224
260
  def _artefact_type(cls) -> ArtefactType:
225
261
  return ArtefactType.feature
226
262
 
263
+ def _serialize_background(self) -> str:
264
+ """Helper method to dispatch background serialization."""
265
+ if not self.background:
266
+ return ""
267
+ lines = []
268
+ lines.append(" Background:")
269
+ for step in self.background.steps:
270
+ lines.append(f" {step}")
271
+ return "\n".join(lines)
272
+
227
273
  def _serialize_scenario(self, scenario: Union[Scenario, ScenarioOutline]) -> str:
228
274
  """Helper method to dispatch scenario serialization."""
229
275
  if isinstance(scenario, Scenario):
@@ -304,6 +350,10 @@ class FeatureArtefact(Artefact):
304
350
  lines.append(description)
305
351
  lines.append("")
306
352
 
353
+ if self.background:
354
+ lines.append(self._serialize_background())
355
+ lines.append("")
356
+
307
357
  if self.scenarios:
308
358
  for scenario in self.scenarios:
309
359
  lines.append(self._serialize_scenario(scenario))
@@ -316,9 +366,11 @@ class FeatureArtefact(Artefact):
316
366
  fields = super()._parse_common_fields(text)
317
367
 
318
368
  intent = FeatureIntent.deserialize(text)
369
+ background = cls.deserialize_background(text)
319
370
  scenarios = cls.deserialize_scenarios(text)
320
371
 
321
372
  fields['scenarios'] = scenarios
373
+ fields['background'] = background
322
374
  fields['intent'] = intent
323
375
 
324
376
  return cls(**fields)
@@ -343,3 +395,19 @@ class FeatureArtefact(Artefact):
343
395
  else:
344
396
  idx += 1
345
397
  return scenarios
398
+
399
+ @classmethod
400
+ def deserialize_background(cls, text):
401
+ lines = [line.strip()
402
+ for line in text.strip().splitlines() if line.strip()]
403
+
404
+ background = None
405
+ idx = 0
406
+ while idx < len(lines):
407
+ line = lines[idx].strip()
408
+ if line.startswith('Background:'):
409
+ background, next_idx = Background.from_lines(lines, idx)
410
+ break
411
+ else:
412
+ idx += 1
413
+ return background
@@ -33,9 +33,14 @@ class KeyfeatureIntent(Intent):
33
33
  return v
34
34
 
35
35
  def serialize(self):
36
+ from ara_cli.artefact_models.serialize_helper import as_a_serializer
37
+
36
38
  lines = []
39
+
40
+ as_a_line = as_a_serializer(self.as_a)
41
+
37
42
  lines.append(f"In order to {self.in_order_to}")
38
- lines.append(f"As a {self.as_a}")
43
+ lines.append(as_a_line)
39
44
  lines.append(f"I want {self.i_want}")
40
45
 
41
46
  return "\n".join(lines)
@@ -0,0 +1,18 @@
1
+ def as_a_serializer(as_a):
2
+ role = as_a.strip()
3
+
4
+ exceptions_for_a = ('user', 'university', 'one-time', 'european', 'unit')
5
+ exceptions_for_an = ('hour', 'honest', 'heir')
6
+ role_lower = role.lower()
7
+ as_a_prefix = ""
8
+
9
+ if any(role_lower.startswith(e) for e in exceptions_for_a):
10
+ as_a_prefix = "As a"
11
+ elif any(role_lower.startswith(e) for e in exceptions_for_an):
12
+ as_a_prefix = "As an"
13
+ elif role_lower.startswith(('a', 'e', 'i', 'o', 'u')):
14
+ as_a_prefix = "As an"
15
+ else:
16
+ as_a_prefix = "As a"
17
+
18
+ return f"{as_a_prefix} {role}"
@@ -33,9 +33,14 @@ class UserstoryIntent(Intent):
33
33
  return v
34
34
 
35
35
  def serialize(self):
36
+ from ara_cli.artefact_models.serialize_helper import as_a_serializer
37
+
36
38
  lines = []
39
+
40
+ as_a_line = as_a_serializer(self.as_a)
41
+
37
42
  lines.append(f"In order to {self.in_order_to}")
38
- lines.append(f"As a {self.as_a}")
43
+ lines.append(as_a_line)
39
44
  lines.append(f"I want {self.i_want}")
40
45
 
41
46
  return "\n".join(lines)
@@ -25,6 +25,8 @@ def find_invalid_files(classified_artefact_info, classifier):
25
25
  for artefact_info in classified_artefact_info[classifier]:
26
26
  if "templates/" in artefact_info["file_path"]:
27
27
  continue
28
+ if ".data" in artefact_info["file_path"]:
29
+ continue
28
30
  is_valid, reason = check_file(artefact_info["file_path"], artefact_class)
29
31
  if not is_valid:
30
32
  invalid_files.append((artefact_info["file_path"], reason))
@@ -184,10 +184,14 @@ def handle_existing_file(filename, block_content):
184
184
  create_file_if_not_exist(filename, block_content)
185
185
  else:
186
186
  print(f"File {filename} exists, creating modification prompt")
187
- prompt = create_prompt_for_file_modification(block_content, filename)
187
+ prompt_text = create_prompt_for_file_modification(block_content, filename)
188
+ messages = [{"role": "user", "content": prompt_text}]
188
189
  response = ""
189
- for chunk in send_prompt(prompt):
190
- response += chunk.content
190
+
191
+ for chunk in send_prompt(messages):
192
+ content = chunk.choices[0].delta.content
193
+ if content:
194
+ response += content
191
195
  modify_and_save_file(response, filename)
192
196
 
193
197
 
@@ -355,8 +355,12 @@ def prepend_system_prompt(message_list):
355
355
 
356
356
 
357
357
  def append_images_to_message(message, image_data_list):
358
- message_content = message["content"]
359
- message["content"] = message_content + image_data_list
358
+ if not image_data_list:
359
+ return message
360
+ new_content_list = [{"type": "text", "text": message}]
361
+ new_content_list.extend(image_data_list)
362
+
363
+ message["content"] = new_content_list
360
364
 
361
365
  return message
362
366
 
@@ -376,14 +380,23 @@ def create_and_send_custom_prompt(classifier, parameter):
376
380
  append_headings(classifier, parameter, "prompt")
377
381
  write_prompt_result(classifier, parameter, prompt)
378
382
 
379
- message_list = append_images_to_message(combined_content_markdown, image_data_list)
380
- append_headings(classifier, parameter, "result")
383
+ base_message = {
384
+ "role": "user",
385
+ "content": combined_content_markdown
386
+ }
387
+
388
+ final_message = append_images_to_message(base_message, image_data_list)
381
389
 
390
+ message_list_to_send = [final_message]
391
+
392
+ append_headings(classifier, parameter, "result")
382
393
  artefact_data_path = f"ara/{sub_directory}/{parameter}.data/{classifier}.prompt_log.md"
383
394
  with open(artefact_data_path, 'a') as file:
384
- for chunk in send_prompt(message_list):
385
- file.write(chunk.content)
386
- file.flush()
395
+ for chunk in send_prompt(message_list_to_send):
396
+ content = chunk.choices[0].delta.content
397
+ if content:
398
+ file.write(content)
399
+ file.flush()
387
400
  # write_prompt_result(classifier, parameter, response)
388
401
 
389
402
 
@@ -0,0 +1,56 @@
1
+ import os
2
+ from ara_cli.artefact_models.artefact_load import artefact_from_content
3
+
4
+
5
+ class TagExtractor:
6
+ def __init__(self, file_system=None):
7
+ self.file_system = file_system or os
8
+
9
+ def extract_tags(self, navigate_to_target=False, include_classifier=None, filtered_extra_column=False):
10
+ from ara_cli.template_manager import DirectoryNavigator
11
+ from ara_cli.artefact_reader import ArtefactReader
12
+
13
+ navigator = DirectoryNavigator()
14
+ if navigate_to_target:
15
+ navigator.navigate_to_target()
16
+
17
+ artefacts = ArtefactReader.read_artefacts()
18
+
19
+ if include_classifier:
20
+ artefacts = {include_classifier: artefacts[include_classifier]}
21
+
22
+ unique_tags = set()
23
+
24
+ if filtered_extra_column:
25
+ status_tags = {"to-do", "in-progress", "review", "done", "closed"}
26
+ filtered_artefacts = []
27
+
28
+ for artefact_list in artefacts.values():
29
+ for artefact in artefact_list:
30
+ tags = artefact.tags + \
31
+ [artefact.status] if artefact.status else artefact.tags
32
+ tag_set = set(tag for tag in tags if tag is not None)
33
+ if not tag_set & status_tags:
34
+ filtered_artefacts.append(artefact)
35
+
36
+ for artefact in filtered_artefacts:
37
+ tags = [tag for tag in (
38
+ artefact.tags + [artefact.status]) if tag is not None]
39
+ for tag in tags:
40
+ if (
41
+ tag in status_tags
42
+ or tag.startswith("priority_")
43
+ or tag.startswith("user_")
44
+ ):
45
+ continue
46
+ unique_tags.add(tag)
47
+
48
+ else:
49
+ for artefact_list in artefacts.values():
50
+ for artefact in artefact_list:
51
+ user_tags = [f"user_{tag}" for tag in artefact.users]
52
+ tags = [tag for tag in (artefact.tags + [artefact.status] + user_tags) if tag is not None]
53
+ unique_tags.update(tags)
54
+
55
+ sorted_tags = sorted(unique_tags)
56
+ return sorted_tags
@@ -1,2 +1,2 @@
1
1
  # version.py
2
- __version__ = "0.1.9.62" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
2
+ __version__ = "0.1.9.64" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ara_cli
3
- Version: 0.1.9.62
3
+ Version: 0.1.9.64
4
4
  Requires-Dist: litellm
5
5
  Requires-Dist: llama-index
6
6
  Requires-Dist: llama-index-llms-openai
@@ -52,6 +52,7 @@ ara_cli/artefact_models/example_artefact_model.py
52
52
  ara_cli/artefact_models/feature_artefact_model.py
53
53
  ara_cli/artefact_models/issue_artefact_model.py
54
54
  ara_cli/artefact_models/keyfeature_artefact_model.py
55
+ ara_cli/artefact_models/serialize_helper.py
55
56
  ara_cli/artefact_models/task_artefact_model.py
56
57
  ara_cli/artefact_models/userstory_artefact_model.py
57
58
  ara_cli/artefact_models/vision_artefact_model.py
@@ -1,31 +0,0 @@
1
- import os
2
- from ara_cli.artefact_models.artefact_load import artefact_from_content
3
-
4
-
5
- class TagExtractor:
6
- def __init__(self, file_system=None):
7
- self.file_system = file_system or os
8
-
9
- def extract_tags(self, navigate_to_target=False, include_classifier=None):
10
- from ara_cli.template_manager import DirectoryNavigator
11
- from ara_cli.artefact_reader import ArtefactReader
12
-
13
- navigator = DirectoryNavigator()
14
- if navigate_to_target:
15
- navigator.navigate_to_target()
16
-
17
- artefacts = ArtefactReader.read_artefacts()
18
-
19
- if include_classifier:
20
- artefacts = {include_classifier: artefacts[include_classifier]}
21
-
22
- unique_tags = set()
23
-
24
- for artefact_list in artefacts.values():
25
- for artefact in artefact_list:
26
- user_tags = [f"user_{tag}" for tag in artefact.users]
27
- tags = [tag for tag in (artefact.tags + [artefact.status] + user_tags) if tag is not None]
28
- unique_tags.update(tags)
29
-
30
- sorted_tags = sorted(unique_tags)
31
- return sorted_tags
File without changes
File without changes
File without changes
File without changes
File without changes