ara-cli 0.1.10.1__tar.gz → 0.1.10.4__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.
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/PKG-INFO +1 -1
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/__main__.py +120 -1
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_autofix.py +44 -6
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/artefact_model.py +18 -6
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/epic_artefact_model.py +11 -2
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/feature_artefact_model.py +31 -1
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/userstory_artefact_model.py +13 -1
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/chat.py +0 -19
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/text_file_loader.py +2 -2
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/prompt_extractor.py +97 -79
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/prompt_handler.py +160 -59
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/tag_extractor.py +26 -23
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/template_loader.py +1 -1
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/version.py +1 -1
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli.egg-info/PKG-INFO +1 -1
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_prompt_handler.py +12 -4
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/MANIFEST.in +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/README.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/__init__.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_command_action.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_config.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/__init__.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/autofix.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/chat.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/classifier_directory.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/common.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/create.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/delete.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/extract.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/fetch_templates.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/list.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/list_tags.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/load.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/prompt.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/read.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/read_status.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/read_user.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/reconnect.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/rename.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/scan.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/set_status.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/set_user.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/ara_subcommands/template.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_creator.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_deleter.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_fuzzy_search.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_link_updater.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_lister.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/__init__.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/artefact_data_retrieval.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/artefact_load.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/artefact_mapping.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/artefact_templates.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/businessgoal_artefact_model.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/capability_artefact_model.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/example_artefact_model.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/issue_artefact_model.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/keyfeature_artefact_model.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/serialize_helper.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/task_artefact_model.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_models/vision_artefact_model.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_reader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_renamer.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/artefact_scan.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/classifier.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/codefusionretriever.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/codehierachieretriever.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/commandline_completer.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/commands/__init__.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/commands/command.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/commands/extract_command.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/commands/load_command.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/commands/load_image_command.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/commands/read_command.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/completers.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/directory_navigator.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/error_handler.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_classifier.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_lister.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/__init__.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/binary_file_loader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/document_file_loader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/document_reader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/document_readers.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/file_loader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/file_loaders.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/image_processor.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/file_loaders/markdown_reader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/filename_validator.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/global_file_lister.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/list_filter.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/output_suppressor.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/prompt_chat.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/prompt_rag.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/run_file_lister.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/template_manager.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/agile.artefacts +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/blueprints/empty.blueprint.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_C4_architecture_analysis.blueprint.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/architecture_C4_analysis.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/architecture_radon_cc_score.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/architecture_radon_halstead_v.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/architecture_radon_maintainability_score.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/empty.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/classify_task.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/empty.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/error_fixing.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/feature_fix_steps_for_scenario.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/feature_formulation.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/feature_reverse_formulation_from_code.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation_update.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/feature_scenario_outline_extension.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/feature_update_formulation.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/fibonacci_example_implementation.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/js_implementation_from_task_description.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/js_steps_implementation.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/python_cli_implementation_with_test.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/python_code_understanding.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/task_implementation.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/task_prompt_control_by_status.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_number.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_status.intention.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/architecture_analyst.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/code_analyst.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/empty.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/error_analyst.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/gherkin_expert.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/js_expert_developer.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/product_owner.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/python_behave.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/prompt-modules/rules/python_developer.rules.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.concept.exploration.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.concept.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.customer.exploration.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.customer.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.persona.exploration.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.persona.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.step.exploration.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.step.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.technology.exploration.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/specification_breakdown_files/template.technology.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.businessgoal.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.capability.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.epic.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.example.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.feature.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.issue.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.keyfeature.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.steps.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.task.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.userstory.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/templates/template.vision.prompt_log.md +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli/update_config_prompt.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli.egg-info/SOURCES.txt +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli.egg-info/dependency_links.txt +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli.egg-info/entry_points.txt +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli.egg-info/requires.txt +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/ara_cli.egg-info/top_level.txt +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/docker/base/requirements.txt +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/setup.cfg +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/setup.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/__init__.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_ara_command_action.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_ara_config.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_artefact_autofix.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_artefact_fuzzy_search.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_artefact_link_updater.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_artefact_lister.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_artefact_reader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_artefact_renamer.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_artefact_scan.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_chat.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_classifier.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_directory_navigator.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_file_classifier.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_file_creator.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_file_lister.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_global_file_lister.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_list_filter.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_tag_extractor.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_template_loader.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/tests/test_template_manager.py +0 -0
- {ara_cli-0.1.10.1 → ara_cli-0.1.10.4}/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.
|
|
3
|
+
Version: 0.1.10.4
|
|
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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
import sys
|
|
3
|
+
import os
|
|
3
4
|
from typing import Optional
|
|
4
5
|
from os import getenv
|
|
5
6
|
from ara_cli.error_handler import AraError
|
|
@@ -44,6 +45,113 @@ def configure_debug_mode(debug: bool, env_debug_mode: bool):
|
|
|
44
45
|
error_handler.debug_mode = True
|
|
45
46
|
|
|
46
47
|
|
|
48
|
+
def find_ara_directory_root():
|
|
49
|
+
"""Find the root ara directory by traversing up the directory tree."""
|
|
50
|
+
current_dir = os.getcwd()
|
|
51
|
+
|
|
52
|
+
# Check if we're already inside an ara directory structure
|
|
53
|
+
path_parts = current_dir.split(os.sep)
|
|
54
|
+
|
|
55
|
+
# Look for 'ara' in the path parts
|
|
56
|
+
if 'ara' in path_parts:
|
|
57
|
+
ara_index = path_parts.index('ara')
|
|
58
|
+
# Reconstruct path up to and including 'ara'
|
|
59
|
+
ara_root_parts = path_parts[:ara_index + 1]
|
|
60
|
+
potential_ara_root = os.sep.join(ara_root_parts)
|
|
61
|
+
if os.path.exists(potential_ara_root) and os.path.isdir(potential_ara_root):
|
|
62
|
+
return potential_ara_root
|
|
63
|
+
|
|
64
|
+
# If not inside ara directory, check current directory and parents
|
|
65
|
+
check_dir = current_dir
|
|
66
|
+
while check_dir != os.path.dirname(check_dir): # Stop at filesystem root
|
|
67
|
+
ara_path = os.path.join(check_dir, 'ara')
|
|
68
|
+
if os.path.exists(ara_path) and os.path.isdir(ara_path):
|
|
69
|
+
return ara_path
|
|
70
|
+
check_dir = os.path.dirname(check_dir)
|
|
71
|
+
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def check_ara_directory_exists():
|
|
76
|
+
"""Check if ara directory exists or if we're inside ara directory tree."""
|
|
77
|
+
return find_ara_directory_root() is not None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def prompt_create_ara_directory():
|
|
81
|
+
"""Prompt user to create ara directory and create it if confirmed."""
|
|
82
|
+
# Print the prompt message
|
|
83
|
+
print("No 'ara' directory found. Create one in the current directory? (Y/n)", end=" ", flush=True)
|
|
84
|
+
|
|
85
|
+
# Read user input
|
|
86
|
+
try:
|
|
87
|
+
response = input().strip()
|
|
88
|
+
except (EOFError, KeyboardInterrupt):
|
|
89
|
+
typer.echo("\nOperation cancelled.")
|
|
90
|
+
raise typer.Exit(1)
|
|
91
|
+
|
|
92
|
+
if response.lower() in ('y', 'yes', ''):
|
|
93
|
+
current_dir = os.getcwd()
|
|
94
|
+
ara_path = os.path.join(current_dir, 'ara')
|
|
95
|
+
|
|
96
|
+
# Create ara directory structure
|
|
97
|
+
subdirectories = [
|
|
98
|
+
'businessgoals',
|
|
99
|
+
'capabilities',
|
|
100
|
+
'epics',
|
|
101
|
+
'examples',
|
|
102
|
+
'features',
|
|
103
|
+
'keyfeatures',
|
|
104
|
+
'tasks',
|
|
105
|
+
'userstories',
|
|
106
|
+
'vision'
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
# Create main ara directory
|
|
111
|
+
os.makedirs(ara_path, exist_ok=True)
|
|
112
|
+
|
|
113
|
+
# Create subdirectories for artefact types
|
|
114
|
+
for subdir in subdirectories:
|
|
115
|
+
os.makedirs(os.path.join(ara_path, subdir), exist_ok=True)
|
|
116
|
+
|
|
117
|
+
# Create .araconfig directory
|
|
118
|
+
araconfig_path = os.path.join(ara_path, '.araconfig')
|
|
119
|
+
os.makedirs(araconfig_path, exist_ok=True)
|
|
120
|
+
|
|
121
|
+
# Create default ara_config.json using ConfigManager
|
|
122
|
+
from ara_cli.ara_config import ConfigManager, ARAconfig
|
|
123
|
+
config_file_path = os.path.join(araconfig_path, 'ara_config.json')
|
|
124
|
+
|
|
125
|
+
# Reset ConfigManager to ensure clean state
|
|
126
|
+
ConfigManager.reset()
|
|
127
|
+
|
|
128
|
+
# Create default config and save it
|
|
129
|
+
default_config = ARAconfig()
|
|
130
|
+
from ara_cli.ara_config import save_data
|
|
131
|
+
save_data(config_file_path, default_config)
|
|
132
|
+
|
|
133
|
+
typer.echo(f"Created ara directory structure at {ara_path}")
|
|
134
|
+
typer.echo(f"Created default configuration at {config_file_path}")
|
|
135
|
+
return True
|
|
136
|
+
|
|
137
|
+
except OSError as e:
|
|
138
|
+
typer.echo(f"Error creating ara directory: {e}", err=True)
|
|
139
|
+
raise typer.Exit(1)
|
|
140
|
+
except Exception as e:
|
|
141
|
+
typer.echo(f"Error creating configuration file: {e}", err=True)
|
|
142
|
+
raise typer.Exit(1)
|
|
143
|
+
else:
|
|
144
|
+
typer.echo("Ara directory creation cancelled.")
|
|
145
|
+
raise typer.Exit(0)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def requires_ara_directory():
|
|
149
|
+
"""Check if ara directory exists and prompt to create if not."""
|
|
150
|
+
if not check_ara_directory_exists():
|
|
151
|
+
return prompt_create_ara_directory()
|
|
152
|
+
return True
|
|
153
|
+
|
|
154
|
+
|
|
47
155
|
def create_app():
|
|
48
156
|
app = typer.Typer(
|
|
49
157
|
help="""The ara cli terminal tool is a management tool for classified ara artefacts.
|
|
@@ -124,6 +232,17 @@ ara chat examples:
|
|
|
124
232
|
if ctx.invoked_subcommand is None:
|
|
125
233
|
ctx.get_help()
|
|
126
234
|
ctx.exit()
|
|
235
|
+
|
|
236
|
+
# Check for ara directory before executing any command
|
|
237
|
+
# Skip check for commands that don't require ara directory
|
|
238
|
+
commands_requiring_ara = {
|
|
239
|
+
'create', 'delete', 'rename', 'list', 'list-tags', 'prompt',
|
|
240
|
+
'read', 'reconnect', 'read-status', 'read-user', 'set-status',
|
|
241
|
+
'set-user', 'classifier-directory', 'scan', 'autofix'
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if ctx.invoked_subcommand in commands_requiring_ara:
|
|
245
|
+
requires_ara_directory()
|
|
127
246
|
|
|
128
247
|
# Register all commands
|
|
129
248
|
register_create_cli(app)
|
|
@@ -162,4 +281,4 @@ def cli():
|
|
|
162
281
|
|
|
163
282
|
|
|
164
283
|
if __name__ == "__main__":
|
|
165
|
-
cli()
|
|
284
|
+
cli()
|
|
@@ -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"
|
|
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"
|
|
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
|
-
"
|
|
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("
|
|
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
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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
|
|
@@ -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:
|
|
@@ -13,25 +13,6 @@ from ara_cli.file_loaders.binary_file_loader import BinaryFileLoader
|
|
|
13
13
|
from ara_cli.file_loaders.text_file_loader import TextFileLoader
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
extract_parser = argparse.ArgumentParser()
|
|
17
|
-
extract_parser.add_argument(
|
|
18
|
-
"-f", "--force", action="store_true", help="Force extraction"
|
|
19
|
-
)
|
|
20
|
-
extract_parser.add_argument(
|
|
21
|
-
"-w",
|
|
22
|
-
"--write",
|
|
23
|
-
action="store_true",
|
|
24
|
-
help="Overwrite existing files without using LLM for merging.",
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
load_parser = argparse.ArgumentParser()
|
|
28
|
-
load_parser.add_argument("file_name", nargs="?", default="", help="File to load")
|
|
29
|
-
load_parser.add_argument(
|
|
30
|
-
"--load-images",
|
|
31
|
-
action="store_true",
|
|
32
|
-
help="Extract and describe images from documents",
|
|
33
|
-
)
|
|
34
|
-
|
|
35
16
|
extract_parser = argparse.ArgumentParser()
|
|
36
17
|
extract_parser.add_argument(
|
|
37
18
|
"-f", "--force", action="store_true", help="Force extraction"
|
|
@@ -19,14 +19,14 @@ class TextFileLoader(FileLoader):
|
|
|
19
19
|
|
|
20
20
|
if is_md_file and extract_images:
|
|
21
21
|
reader = MarkdownReader(file_path)
|
|
22
|
-
file_content = reader.read(extract_images=True)
|
|
22
|
+
file_content = reader.read(extract_images=True).replace('\r\n', '\n')
|
|
23
23
|
else:
|
|
24
24
|
# Use charset-normalizer to detect encoding
|
|
25
25
|
encoded_content = from_path(file_path).best()
|
|
26
26
|
if not encoded_content:
|
|
27
27
|
print(f"Failed to detect encoding for {file_path}")
|
|
28
28
|
return False
|
|
29
|
-
file_content = str(encoded_content)
|
|
29
|
+
file_content = str(encoded_content).replace('\r\n', '\n')
|
|
30
30
|
|
|
31
31
|
if block_delimiter:
|
|
32
32
|
file_content = f"{block_delimiter}\n{file_content}\n{block_delimiter}"
|