ara-cli 0.1.10.5__py3-none-any.whl → 0.1.14.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. ara_cli/__init__.py +51 -6
  2. ara_cli/__main__.py +87 -75
  3. ara_cli/ara_command_action.py +189 -101
  4. ara_cli/ara_config.py +187 -128
  5. ara_cli/ara_subcommands/common.py +2 -2
  6. ara_cli/ara_subcommands/config.py +221 -0
  7. ara_cli/ara_subcommands/convert.py +107 -0
  8. ara_cli/ara_subcommands/fetch.py +41 -0
  9. ara_cli/ara_subcommands/fetch_agents.py +22 -0
  10. ara_cli/ara_subcommands/fetch_scripts.py +19 -0
  11. ara_cli/ara_subcommands/fetch_templates.py +15 -10
  12. ara_cli/ara_subcommands/list.py +97 -23
  13. ara_cli/ara_subcommands/prompt.py +266 -106
  14. ara_cli/artefact_autofix.py +117 -64
  15. ara_cli/artefact_converter.py +355 -0
  16. ara_cli/artefact_creator.py +41 -17
  17. ara_cli/artefact_lister.py +3 -3
  18. ara_cli/artefact_models/artefact_model.py +1 -1
  19. ara_cli/artefact_models/artefact_templates.py +0 -9
  20. ara_cli/artefact_models/feature_artefact_model.py +8 -8
  21. ara_cli/artefact_reader.py +62 -43
  22. ara_cli/artefact_scan.py +39 -17
  23. ara_cli/chat.py +300 -71
  24. ara_cli/chat_agent/__init__.py +0 -0
  25. ara_cli/chat_agent/agent_process_manager.py +155 -0
  26. ara_cli/chat_script_runner/__init__.py +0 -0
  27. ara_cli/chat_script_runner/script_completer.py +23 -0
  28. ara_cli/chat_script_runner/script_finder.py +41 -0
  29. ara_cli/chat_script_runner/script_lister.py +36 -0
  30. ara_cli/chat_script_runner/script_runner.py +36 -0
  31. ara_cli/chat_web_search/__init__.py +0 -0
  32. ara_cli/chat_web_search/web_search.py +263 -0
  33. ara_cli/children_contribution_updater.py +737 -0
  34. ara_cli/classifier.py +34 -0
  35. ara_cli/commands/agent_run_command.py +98 -0
  36. ara_cli/commands/fetch_agents_command.py +106 -0
  37. ara_cli/commands/fetch_scripts_command.py +43 -0
  38. ara_cli/commands/fetch_templates_command.py +39 -0
  39. ara_cli/commands/fetch_templates_commands.py +39 -0
  40. ara_cli/commands/list_agents_command.py +39 -0
  41. ara_cli/commands/load_command.py +4 -3
  42. ara_cli/commands/load_image_command.py +1 -1
  43. ara_cli/commands/read_command.py +23 -27
  44. ara_cli/completers.py +95 -35
  45. ara_cli/constants.py +2 -0
  46. ara_cli/directory_navigator.py +37 -4
  47. ara_cli/error_handler.py +26 -11
  48. ara_cli/file_loaders/document_reader.py +0 -178
  49. ara_cli/file_loaders/factories/__init__.py +0 -0
  50. ara_cli/file_loaders/factories/document_reader_factory.py +32 -0
  51. ara_cli/file_loaders/factories/file_loader_factory.py +27 -0
  52. ara_cli/file_loaders/file_loader.py +1 -30
  53. ara_cli/file_loaders/loaders/__init__.py +0 -0
  54. ara_cli/file_loaders/{document_file_loader.py → loaders/document_file_loader.py} +1 -1
  55. ara_cli/file_loaders/loaders/text_file_loader.py +47 -0
  56. ara_cli/file_loaders/readers/__init__.py +0 -0
  57. ara_cli/file_loaders/readers/docx_reader.py +49 -0
  58. ara_cli/file_loaders/readers/excel_reader.py +27 -0
  59. ara_cli/file_loaders/{markdown_reader.py → readers/markdown_reader.py} +1 -1
  60. ara_cli/file_loaders/readers/odt_reader.py +59 -0
  61. ara_cli/file_loaders/readers/pdf_reader.py +54 -0
  62. ara_cli/file_loaders/readers/pptx_reader.py +104 -0
  63. ara_cli/file_loaders/tools/__init__.py +0 -0
  64. ara_cli/llm_utils.py +58 -0
  65. ara_cli/output_suppressor.py +53 -0
  66. ara_cli/prompt_chat.py +20 -4
  67. ara_cli/prompt_extractor.py +47 -32
  68. ara_cli/prompt_handler.py +123 -17
  69. ara_cli/tag_extractor.py +8 -7
  70. ara_cli/template_loader.py +2 -1
  71. ara_cli/template_manager.py +52 -21
  72. ara_cli/templates/global-scripts/hello_global.py +1 -0
  73. ara_cli/templates/prompt-modules/commands/add_scenarios_for_new_behaviour.feature_creation_agent.commands.md +1 -0
  74. ara_cli/templates/prompt-modules/commands/align_feature_with_implementation_changes.interview_agent.commands.md +1 -0
  75. ara_cli/templates/prompt-modules/commands/analyze_codebase_and_plan_tasks.interview_agent.commands.md +1 -0
  76. ara_cli/templates/prompt-modules/commands/choose_best_parent_artefact.interview_agent.commands.md +1 -0
  77. ara_cli/templates/prompt-modules/commands/create_tasks_from_artefact_content.interview_agent.commands.md +1 -0
  78. ara_cli/templates/prompt-modules/commands/create_tests_for_uncovered_modules.test_generation_agent.commands.md +1 -0
  79. ara_cli/templates/prompt-modules/commands/derive_features_from_video_description.feature_creation_agent.commands.md +1 -0
  80. ara_cli/templates/prompt-modules/commands/describe_agent_capabilities.agent.commands.md +1 -0
  81. ara_cli/templates/prompt-modules/commands/empty.commands.md +2 -12
  82. ara_cli/templates/prompt-modules/commands/execute_scoped_todos_in_task.interview_agent.commands.md +1 -0
  83. ara_cli/templates/prompt-modules/commands/explain_single_file_purpose.interview_agent.commands.md +1 -0
  84. ara_cli/templates/prompt-modules/commands/extract_file_information_bullets.interview_agent.commands.md +1 -0
  85. ara_cli/templates/prompt-modules/commands/extract_general.commands.md +12 -0
  86. ara_cli/templates/prompt-modules/commands/extract_markdown.commands.md +11 -0
  87. ara_cli/templates/prompt-modules/commands/extract_python.commands.md +13 -0
  88. ara_cli/templates/prompt-modules/commands/feature_add_or_modifiy_specified_behavior.commands.md +36 -0
  89. ara_cli/templates/prompt-modules/commands/feature_generate_initial_specified_bevahior.commands.md +53 -0
  90. ara_cli/templates/prompt-modules/commands/fix_failing_behave_step_definitions.interview_agent.commands.md +1 -0
  91. ara_cli/templates/prompt-modules/commands/fix_failing_pytest_tests.interview_agent.commands.md +1 -0
  92. ara_cli/templates/prompt-modules/commands/general_instruction_policy.commands.md +47 -0
  93. ara_cli/templates/prompt-modules/commands/generate_and_fix_pytest_tests.test_generation_agent.commands.md +1 -0
  94. ara_cli/templates/prompt-modules/commands/prompt_template_tech_stack_transformer.commands.md +95 -0
  95. ara_cli/templates/prompt-modules/commands/python_bug_fixing_code.commands.md +34 -0
  96. ara_cli/templates/prompt-modules/commands/python_generate_code.commands.md +27 -0
  97. ara_cli/templates/prompt-modules/commands/python_refactoring_code.commands.md +39 -0
  98. ara_cli/templates/prompt-modules/commands/python_step_definitions_generation_and_fixing.commands.md +40 -0
  99. ara_cli/templates/prompt-modules/commands/python_unittest_generation_and_fixing.commands.md +48 -0
  100. ara_cli/templates/prompt-modules/commands/suggest_next_story_child_tasks.interview_agent.commands.md +1 -0
  101. ara_cli/templates/prompt-modules/commands/summarize_or_transcribe_media.interview_agent.commands.md +1 -0
  102. ara_cli/templates/prompt-modules/commands/update_feature_to_match_implementation.feature_creation_agent.commands.md +1 -0
  103. ara_cli/templates/prompt-modules/commands/update_user_story_with_requirements.interview_agent.commands.md +1 -0
  104. ara_cli/version.py +1 -1
  105. {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/METADATA +49 -11
  106. ara_cli-0.1.14.0.dist-info/RECORD +253 -0
  107. {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/WHEEL +1 -1
  108. tests/test_ara_command_action.py +31 -19
  109. tests/test_ara_config.py +177 -90
  110. tests/test_artefact_autofix.py +170 -97
  111. tests/test_artefact_autofix_integration.py +495 -0
  112. tests/test_artefact_converter.py +312 -0
  113. tests/test_artefact_extraction.py +564 -0
  114. tests/test_artefact_lister.py +11 -8
  115. tests/test_chat.py +166 -130
  116. tests/test_chat_givens_images.py +603 -0
  117. tests/test_chat_script_runner.py +454 -0
  118. tests/test_children_contribution_updater.py +98 -0
  119. tests/test_document_loader_office.py +267 -0
  120. tests/test_llm_utils.py +164 -0
  121. tests/test_prompt_chat.py +343 -0
  122. tests/test_prompt_extractor.py +683 -0
  123. tests/test_prompt_handler.py +416 -214
  124. tests/test_setup_default_chat_prompt_mode.py +198 -0
  125. tests/test_tag_extractor.py +95 -49
  126. tests/test_web_search.py +467 -0
  127. ara_cli/file_loaders/document_readers.py +0 -233
  128. ara_cli/file_loaders/file_loaders.py +0 -123
  129. ara_cli/file_loaders/text_file_loader.py +0 -187
  130. ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -27
  131. ara_cli/templates/prompt-modules/blueprints/pytest_unittest_prompt.blueprint.md +0 -32
  132. ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -30
  133. ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -9
  134. ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -17
  135. ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -14
  136. ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -102
  137. ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -20
  138. ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -13
  139. ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -20
  140. ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -18
  141. ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -43
  142. ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -13
  143. ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -15
  144. ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -9
  145. ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -15
  146. ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -19
  147. ara_cli-0.1.10.5.dist-info/RECORD +0 -194
  148. /ara_cli/file_loaders/{binary_file_loader.py → loaders/binary_file_loader.py} +0 -0
  149. /ara_cli/file_loaders/{image_processor.py → tools/image_processor.py} +0 -0
  150. {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/entry_points.txt +0 -0
  151. {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/top_level.txt +0 -0
@@ -23,23 +23,43 @@ def create_action(args):
23
23
  from ara_cli.artefact_reader import ArtefactReader
24
24
  from ara_cli.artefact_fuzzy_search import find_closest_rule
25
25
 
26
- check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
27
- check_validity(is_valid_filename(args.parameter), "Invalid filename provided. Please provide a valid filename.")
26
+ check_validity(
27
+ Classifier.is_valid_classifier(args.classifier),
28
+ "Invalid classifier provided. Please provide a valid classifier.",
29
+ )
30
+ check_validity(
31
+ is_valid_filename(args.parameter),
32
+ "Invalid filename provided. Please provide a valid filename.",
33
+ )
28
34
 
29
35
  def handle_parent_arguments(args):
30
- parent_classifier = args.parent_classifier if hasattr(args, "parent_classifier") else None
36
+ parent_classifier = (
37
+ args.parent_classifier if hasattr(args, "parent_classifier") else None
38
+ )
31
39
  parent_name = args.parent_name if hasattr(args, "parent_name") else None
32
- rule = args.rule if hasattr(args, 'rule') else None
33
- invalid_classifier_message = "Invalid parent classifier provided. Please provide a valid classifier"
34
- invalid_name_message = "Invalid filename provided for parent. Please provide a valid filename."
40
+ rule = args.rule if hasattr(args, "rule") else None
41
+ invalid_classifier_message = (
42
+ "Invalid parent classifier provided. Please provide a valid classifier"
43
+ )
44
+ invalid_name_message = (
45
+ "Invalid filename provided for parent. Please provide a valid filename."
46
+ )
35
47
  if parent_classifier and parent_name and rule:
36
- check_validity(Classifier.is_valid_classifier(parent_classifier), invalid_classifier_message)
48
+ check_validity(
49
+ Classifier.is_valid_classifier(parent_classifier),
50
+ invalid_classifier_message,
51
+ )
37
52
  check_validity(is_valid_filename(parent_name), invalid_name_message)
38
- parent_artefact = ArtefactReader.read_artefact(artefact_name=parent_name, classifier=parent_classifier)
53
+ parent_artefact = ArtefactReader().read_artefact(
54
+ artefact_name=parent_name, classifier=parent_classifier
55
+ )
39
56
  rule = find_closest_rule(parent_artefact, rule)
40
57
  return parent_classifier, parent_name, rule
41
58
  if parent_classifier and parent_name:
42
- check_validity(Classifier.is_valid_classifier(parent_classifier), invalid_classifier_message)
59
+ check_validity(
60
+ Classifier.is_valid_classifier(parent_classifier),
61
+ invalid_classifier_message,
62
+ )
43
63
  check_validity(is_valid_filename(parent_name), invalid_name_message)
44
64
  return parent_classifier, parent_name, rule
45
65
  return None, None, None
@@ -61,7 +81,9 @@ def create_action(args):
61
81
  return
62
82
 
63
83
  artefact_creator = ArtefactCreator()
64
- artefact_creator.run(args.parameter, args.classifier, parent_classifier, parent_name, rule)
84
+ artefact_creator.run(
85
+ args.parameter, args.classifier, parent_classifier, parent_name, rule
86
+ )
65
87
 
66
88
 
67
89
  @handle_errors(context="delete action", error_handler=error_handler)
@@ -78,22 +100,39 @@ def rename_action(args):
78
100
  from ara_cli.classifier import Classifier
79
101
  from ara_cli.filename_validator import is_valid_filename
80
102
 
81
- check_validity(is_valid_filename(args.parameter), "Invalid filename provided. Please provide a valid filename.")
82
- check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
83
- check_validity(is_valid_filename(args.aspect), "Invalid new filename provided. Please provide a valid filename.")
103
+ check_validity(
104
+ is_valid_filename(args.parameter),
105
+ "Invalid filename provided. Please provide a valid filename.",
106
+ )
107
+ check_validity(
108
+ Classifier.is_valid_classifier(args.classifier),
109
+ "Invalid classifier provided. Please provide a valid classifier.",
110
+ )
111
+ check_validity(
112
+ is_valid_filename(args.aspect),
113
+ "Invalid new filename provided. Please provide a valid filename.",
114
+ )
84
115
 
85
116
  artefact_renamer = ArtefactRenamer()
86
117
  artefact_renamer.rename(args.parameter, args.aspect, args.classifier)
87
118
 
88
119
 
120
+ def _execute_list_method(method, classifier, artefact_name, list_filter, flag_name):
121
+ """Helper function to validate and execute list methods."""
122
+ if not classifier or not artefact_name:
123
+ raise AraError(
124
+ f"Both classifier and artefact_name are required for --{flag_name}"
125
+ )
126
+ method(classifier=classifier, artefact_name=artefact_name, list_filter=list_filter)
127
+
128
+
89
129
  @handle_errors(context="rename action", error_handler=error_handler)
90
130
  def list_action(args):
91
131
  from ara_cli.artefact_lister import ArtefactLister
92
132
  from ara_cli.list_filter import ListFilter
93
133
 
94
- branch_classifier, branch_artefact_name = args.branch_args
95
- children_classifier, children_artefact_name = args.children_args
96
- data_classifier, data_artefact_name = args.data_args
134
+ classifier = args.classifier
135
+ artefact_name = args.artefact_name
97
136
 
98
137
  artefact_lister = ArtefactLister()
99
138
 
@@ -103,32 +142,30 @@ def list_action(args):
103
142
  include_extension=args.include_extension,
104
143
  exclude_extension=args.exclude_extension,
105
144
  include_tags=args.include_tags,
106
- exclude_tags=args.exclude_tags
145
+ exclude_tags=args.exclude_tags,
107
146
  )
108
147
 
109
- if branch_classifier and branch_artefact_name:
110
- artefact_lister.list_branch(
111
- classifier=branch_classifier,
112
- artefact_name=branch_artefact_name,
113
- list_filter=list_filter
114
- )
115
- return
116
-
117
- if children_classifier and children_artefact_name:
118
- artefact_lister.list_children(
119
- classifier=children_classifier,
120
- artefact_name=children_artefact_name,
121
- list_filter=list_filter
122
- )
123
- return
148
+ # Map flags to their corresponding methods
149
+ flag_method_map = {
150
+ "branch": (args.branch, artefact_lister.list_branch),
151
+ "children": (args.children, artefact_lister.list_children),
152
+ "data": (args.data, artefact_lister.list_data),
153
+ }
124
154
 
125
- if data_classifier and data_artefact_name:
126
- artefact_lister.list_data(
127
- classifier=data_classifier,
128
- artefact_name=data_artefact_name,
129
- list_filter=list_filter
155
+ for flag_name, (flag_value, method) in flag_method_map.items():
156
+ if flag_value:
157
+ _execute_list_method(
158
+ method, classifier, artefact_name, list_filter, flag_name
159
+ )
160
+ return
161
+
162
+ # If both classifier and artefact_name are present, but no specific action flag (branch, children, data)
163
+ # was provided, raise an error as per requirements.
164
+ if classifier and artefact_name:
165
+ raise AraError(
166
+ f"To list specific info for '{classifier} {artefact_name}', "
167
+ "you must provide one of: --children, --branch, or --data."
130
168
  )
131
- return
132
169
 
133
170
  artefact_lister.list_files(list_filter=list_filter)
134
171
 
@@ -146,7 +183,7 @@ def list_tags_action(args):
146
183
  tag_extractor = TagExtractor()
147
184
  tag_groups = tag_extractor.extract_tags(
148
185
  filtered_extra_column=getattr(args, "filtered_extra_column", False),
149
- list_filter=list_filter
186
+ list_filter=list_filter,
150
187
  )
151
188
 
152
189
  if args.json:
@@ -171,66 +208,91 @@ def prompt_action(args):
171
208
  from ara_cli.classifier import Classifier
172
209
  from ara_cli.filename_validator import is_valid_filename
173
210
 
174
- check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
175
- check_validity(is_valid_filename(args.parameter), "Invalid filename provided. Please provide a valid filename.")
211
+ check_validity(
212
+ Classifier.is_valid_classifier(args.classifier),
213
+ "Invalid classifier provided. Please provide a valid classifier.",
214
+ )
215
+ check_validity(
216
+ is_valid_filename(args.parameter),
217
+ "Invalid filename provided. Please provide a valid filename.",
218
+ )
176
219
 
177
220
  classifier = args.classifier
178
221
  param = args.parameter
179
222
  init = args.steps
180
- write = getattr(args, 'write', False)
223
+ write = getattr(args, "write", False)
181
224
 
182
225
  def handle_init():
183
226
  from ara_cli.prompt_handler import initialize_prompt_templates
227
+
184
228
  initialize_prompt_templates(classifier, param)
185
229
 
186
230
  def handle_init_rag():
187
231
  from ara_cli.prompt_handler import initialize_prompt_templates
188
232
  from ara_cli.prompt_rag import search_and_add_relevant_files_to_prompt_givens
233
+
189
234
  initialize_prompt_templates(classifier, param)
190
235
  search_and_add_relevant_files_to_prompt_givens(classifier, param)
191
236
 
192
237
  def handle_load():
193
238
  from ara_cli.prompt_handler import load_selected_prompt_templates
239
+
194
240
  load_selected_prompt_templates(classifier, param)
195
241
 
196
242
  def handle_send():
197
243
  from ara_cli.prompt_handler import create_and_send_custom_prompt
244
+
198
245
  create_and_send_custom_prompt(classifier, param)
199
246
 
200
247
  def handle_load_and_send():
201
- from ara_cli.prompt_handler import load_selected_prompt_templates, create_and_send_custom_prompt
248
+ from ara_cli.prompt_handler import (
249
+ load_selected_prompt_templates,
250
+ create_and_send_custom_prompt,
251
+ )
252
+
202
253
  load_selected_prompt_templates(classifier, param)
203
254
  create_and_send_custom_prompt(classifier, param)
204
255
 
205
256
  def handle_extract():
206
257
  from ara_cli.prompt_extractor import extract_and_save_prompt_results
207
258
  from ara_cli.update_config_prompt import update_artefact_config_prompt_files
259
+
208
260
  extract_and_save_prompt_results(classifier, param, write=write)
209
261
  print(f"automatic update after extract")
210
262
  update_artefact_config_prompt_files(classifier, param, automatic_update=True)
211
263
 
212
264
  def handle_chat():
213
265
  from ara_cli.prompt_chat import initialize_prompt_chat_mode
266
+
214
267
  chat_name = args.chat_name
215
268
  reset = args.reset
216
269
  output_mode = args.output_mode
217
270
  append_strings = args.append
218
271
  restricted = args.restricted
219
- initialize_prompt_chat_mode(classifier, param, chat_name, reset=reset, output_mode=output_mode, append_strings=append_strings, restricted=restricted)
272
+ initialize_prompt_chat_mode(
273
+ classifier,
274
+ param,
275
+ chat_name,
276
+ reset=reset,
277
+ output_mode=output_mode,
278
+ append_strings=append_strings,
279
+ restricted=restricted,
280
+ )
220
281
 
221
282
  def handle_update():
222
283
  from ara_cli.update_config_prompt import update_artefact_config_prompt_files
284
+
223
285
  update_artefact_config_prompt_files(classifier, param, automatic_update=True)
224
286
 
225
287
  command_dispatcher = {
226
- 'init': handle_init,
227
- 'init-rag': handle_init_rag,
228
- 'load': handle_load,
229
- 'send': handle_send,
230
- 'load-and-send': handle_load_and_send,
231
- 'extract': handle_extract,
232
- 'chat': handle_chat,
233
- 'update': handle_update,
288
+ "init": handle_init,
289
+ "init-rag": handle_init_rag,
290
+ "load": handle_load,
291
+ "send": handle_send,
292
+ "load-and-send": handle_load_and_send,
293
+ "extract": handle_extract,
294
+ "chat": handle_chat,
295
+ "update": handle_update,
234
296
  }
235
297
 
236
298
  if init in command_dispatcher:
@@ -255,7 +317,11 @@ def chat_action(args):
255
317
  chat_file_path = join(cwd, chat_name)
256
318
 
257
319
  with suppress_stdout(output_mode):
258
- chat = Chat(chat_file_path, reset=reset) if not restricted else Chat(chat_file_path, reset=reset, enable_commands=whitelisted_commands)
320
+ chat = (
321
+ Chat(chat_file_path, reset=reset)
322
+ if not restricted
323
+ else Chat(chat_file_path, reset=reset, enable_commands=whitelisted_commands)
324
+ )
259
325
 
260
326
  if append_strings:
261
327
  chat.append_strings(append_strings)
@@ -299,20 +365,22 @@ def load_action(args):
299
365
  default_patterns = {
300
366
  "rules": "*.rules.md",
301
367
  "intention": "*.intention.md",
302
- "commands": "*.commands.md"
368
+ "commands": "*.commands.md",
303
369
  }
304
370
 
305
371
  default_pattern = default_patterns.get(template_type)
306
372
 
307
373
  if not template_name and not default_pattern:
308
- raise AraError(f"A template name is required for template type '{template_type}'.")
374
+ raise AraError(
375
+ f"A template name is required for template type '{template_type}'."
376
+ )
309
377
 
310
378
  loader = TemplateLoader() # No chat instance for CLI context
311
379
  success = loader.load_template(
312
380
  template_name=template_name,
313
381
  template_type=template_type,
314
382
  chat_file_path=chat_file_path,
315
- default_pattern=default_pattern
383
+ default_pattern=default_pattern,
316
384
  )
317
385
 
318
386
  if not success:
@@ -324,7 +392,10 @@ def template_action(args):
324
392
  from ara_cli.classifier import Classifier
325
393
  from ara_cli.template_manager import TemplatePathManager
326
394
 
327
- check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
395
+ check_validity(
396
+ Classifier.is_valid_classifier(args.classifier),
397
+ "Invalid classifier provided. Please provide a valid classifier.",
398
+ )
328
399
 
329
400
  template_manager = TemplatePathManager()
330
401
  content = template_manager.get_template_content(args.classifier)
@@ -356,7 +427,9 @@ def fetch_templates_action(args):
356
427
  shutil.copy2(source, target)
357
428
 
358
429
  custom_prompt_templates_subdir = config.custom_prompt_templates_subdir
359
- local_prompt_modules_dir = join(prompt_templates_dir, custom_prompt_templates_subdir)
430
+ local_prompt_modules_dir = join(
431
+ prompt_templates_dir, custom_prompt_templates_subdir
432
+ )
360
433
  os.makedirs(local_prompt_modules_dir, exist_ok=True)
361
434
  for subdir in subdirs:
362
435
  os.makedirs(join(local_prompt_modules_dir, subdir), exist_ok=True)
@@ -377,14 +450,14 @@ def read_action(args):
377
450
  include_extension=args.include_extension,
378
451
  exclude_extension=args.exclude_extension,
379
452
  include_tags=args.include_tags,
380
- exclude_tags=args.exclude_tags
453
+ exclude_tags=args.exclude_tags,
381
454
  )
382
455
 
383
456
  command = ReadCommand(
384
457
  classifier=classifier,
385
458
  artefact_name=artefact_name,
386
459
  read_mode=read_mode,
387
- list_filter=list_filter
460
+ list_filter=list_filter,
388
461
  )
389
462
 
390
463
  command.execute()
@@ -402,7 +475,7 @@ def reconnect_action(args):
402
475
  artefact_name = args.parameter
403
476
  parent_classifier = args.parent_classifier
404
477
  parent_name = args.parent_name
405
- rule = args.rule if hasattr(args, 'rule') else None
478
+ rule = args.rule if hasattr(args, "rule") else None
406
479
 
407
480
  read_error_message = f"Could not connect {classifier} '{artefact_name}' to {parent_classifier} '{parent_name}'"
408
481
 
@@ -411,27 +484,27 @@ def reconnect_action(args):
411
484
  file_classifier = FileClassifier(os)
412
485
  classified_file_info = file_classifier.classify_files()
413
486
 
414
- artefact = ArtefactReader.read_artefact(
487
+ reader = ArtefactReader()
488
+ artefact = reader.read_artefact(
415
489
  artefact_name=artefact_name,
416
490
  classifier=classifier,
417
- classified_file_info=classified_file_info
491
+ classified_file_info=classified_file_info,
418
492
  )
419
493
 
420
494
  if not artefact:
421
495
  raise AraError(read_error_message)
422
496
 
423
- parent = ArtefactReader.read_artefact(
497
+ parent = reader.read_artefact(
424
498
  artefact_name=parent_name,
425
499
  classifier=parent_classifier,
426
- classified_file_info=classified_file_info
500
+ classified_file_info=classified_file_info,
427
501
  )
428
502
 
429
503
  if not parent:
430
504
  raise AraError(read_error_message)
431
505
 
432
506
  contribution = Contribution(
433
- artefact_name=parent.title,
434
- classifier=parent.artefact_type
507
+ artefact_name=parent.title, classifier=parent.artefact_type
435
508
  )
436
509
 
437
510
  if rule:
@@ -440,7 +513,7 @@ def reconnect_action(args):
440
513
  feedback_message += f" using rule '{closest_rule}'"
441
514
 
442
515
  artefact.contribution = contribution
443
- with open(artefact.file_path, 'w', encoding='utf-8') as file:
516
+ with open(artefact.file_path, "w", encoding="utf-8") as file:
444
517
  artefact_content = artefact.serialize()
445
518
  file.write(artefact_content)
446
519
 
@@ -459,16 +532,20 @@ def read_status_action(args):
459
532
  artefact_info = file_classifier.classify_files()
460
533
  artefact_info_dicts = artefact_info.get(classifier, [])
461
534
 
462
- all_artefact_names = [artefact_info["title"] for artefact_info in artefact_info_dicts]
535
+ all_artefact_names = [
536
+ artefact_info["title"] for artefact_info in artefact_info_dicts
537
+ ]
463
538
  if artefact_name not in all_artefact_names:
464
- suggest_close_name_matches(artefact_name, all_artefact_names, report_as_error=True)
539
+ suggest_close_name_matches(
540
+ artefact_name, all_artefact_names, report_as_error=True
541
+ )
465
542
  return
466
543
 
467
- artefact_info = next(filter(
468
- lambda x: x["title"] == artefact_name, artefact_info_dicts
469
- ))
544
+ artefact_info = next(
545
+ filter(lambda x: x["title"] == artefact_name, artefact_info_dicts)
546
+ )
470
547
 
471
- with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
548
+ with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
472
549
  content = file.read()
473
550
  artefact = artefact_from_content(content)
474
551
 
@@ -492,16 +569,20 @@ def read_user_action(args):
492
569
  artefact_info = file_classifier.classify_files()
493
570
  artefact_info_dicts = artefact_info.get(classifier, [])
494
571
 
495
- all_artefact_names = [artefact_info["title"] for artefact_info in artefact_info_dicts]
572
+ all_artefact_names = [
573
+ artefact_info["title"] for artefact_info in artefact_info_dicts
574
+ ]
496
575
  if artefact_name not in all_artefact_names:
497
- suggest_close_name_matches(artefact_name, all_artefact_names, report_as_error=True)
576
+ suggest_close_name_matches(
577
+ artefact_name, all_artefact_names, report_as_error=True
578
+ )
498
579
  return
499
580
 
500
- artefact_info = next(filter(
501
- lambda x: x["title"] == artefact_name, artefact_info_dicts
502
- ))
581
+ artefact_info = next(
582
+ filter(lambda x: x["title"] == artefact_name, artefact_info_dicts)
583
+ )
503
584
 
504
- with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
585
+ with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
505
586
  content = file.read()
506
587
  artefact = artefact_from_content(content)
507
588
 
@@ -526,32 +607,37 @@ def set_status_action(args):
526
607
  artefact_name = args.parameter
527
608
  new_status = args.new_status
528
609
 
529
- if new_status.startswith('@'):
530
- new_status = new_status.lstrip('@')
610
+ if new_status.startswith("@"):
611
+ new_status = new_status.lstrip("@")
531
612
 
532
- check_validity(new_status in status_tags, "Invalid status provided. Please provide a valid status.")
613
+ check_validity(
614
+ new_status in status_tags,
615
+ "Invalid status provided. Please provide a valid status.",
616
+ )
533
617
 
534
618
  file_classifier = FileClassifier(os)
535
619
  classified_artefacts_info = file_classifier.classify_files()
536
620
  classified_artefact_dict = classified_artefacts_info.get(classifier, [])
537
- all_artefact_names = [artefact_info["title"] for artefact_info in classified_artefact_dict]
621
+ all_artefact_names = [
622
+ artefact_info["title"] for artefact_info in classified_artefact_dict
623
+ ]
538
624
 
539
625
  if artefact_name not in all_artefact_names:
540
626
  suggest_close_name_matches(artefact_name, all_artefact_names)
541
627
  return
542
628
 
543
- artefact_info = next(filter(
544
- lambda x: x["title"] == artefact_name, classified_artefact_dict
545
- ))
629
+ artefact_info = next(
630
+ filter(lambda x: x["title"] == artefact_name, classified_artefact_dict)
631
+ )
546
632
 
547
- with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
633
+ with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
548
634
  content = file.read()
549
635
  artefact = artefact_from_content(content)
550
636
 
551
637
  artefact.status = new_status
552
638
 
553
639
  serialized_content = artefact.serialize()
554
- with open(f"{artefact_info['file_path']}", 'w', encoding='utf-8') as file:
640
+ with open(f"{artefact_info['file_path']}", "w", encoding="utf-8") as file:
555
641
  file.write(serialized_content)
556
642
 
557
643
  print(f"Status of task '{artefact_name}' has been updated to '{new_status}'.")
@@ -566,23 +652,25 @@ def set_user_action(args):
566
652
  artefact_name = args.parameter
567
653
  new_user = args.new_user
568
654
 
569
- if new_user.startswith('@'):
570
- new_user = new_user.lstrip('@')
655
+ if new_user.startswith("@"):
656
+ new_user = new_user.lstrip("@")
571
657
 
572
658
  file_classifier = FileClassifier(os)
573
659
  classified_artefacts_info = file_classifier.classify_files()
574
660
  classified_artefact_dict = classified_artefacts_info.get(classifier, [])
575
- all_artefact_names = [artefact_info["title"] for artefact_info in classified_artefact_dict]
661
+ all_artefact_names = [
662
+ artefact_info["title"] for artefact_info in classified_artefact_dict
663
+ ]
576
664
 
577
665
  if artefact_name not in all_artefact_names:
578
666
  suggest_close_name_matches(artefact_name, all_artefact_names)
579
667
  return
580
668
 
581
- artefact_info = next(filter(
582
- lambda x: x["title"] == artefact_name, classified_artefact_dict
583
- ))
669
+ artefact_info = next(
670
+ filter(lambda x: x["title"] == artefact_name, classified_artefact_dict)
671
+ )
584
672
 
585
- with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
673
+ with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
586
674
  content = file.read()
587
675
  artefact = artefact_from_content(content)
588
676
 
@@ -590,7 +678,7 @@ def set_user_action(args):
590
678
 
591
679
  serialized_content = artefact.serialize()
592
680
 
593
- with open(artefact_info["file_path"], 'w', encoding='utf-8') as file:
681
+ with open(artefact_info["file_path"], "w", encoding="utf-8") as file:
594
682
  file.write(serialized_content)
595
683
 
596
684
  print(f"User of task '{artefact_name}' has been updated to '{new_user}'.")
@@ -654,7 +742,7 @@ def autofix_action(args):
654
742
  single_pass=args.single_pass,
655
743
  deterministic=run_deterministic,
656
744
  non_deterministic=run_non_deterministic,
657
- classified_artefact_info=classified_artefact_info
745
+ classified_artefact_info=classified_artefact_info,
658
746
  )
659
747
 
660
748
  print("\nAutofix process completed. Please review the changes.")
@@ -666,11 +754,11 @@ def extract_action(args):
666
754
 
667
755
  filename = args.filename
668
756
  force = args.force
669
- write = getattr(args, 'write', False)
757
+ write = getattr(args, "write", False)
670
758
  command = ExtractCommand(
671
759
  file_name=filename,
672
760
  force=force,
673
761
  write=write,
674
- output=lambda msg: print(msg, file=sys.stdout)
762
+ output=lambda msg: print(msg, file=sys.stdout),
675
763
  )
676
- command.execute()
764
+ command.execute()