ara-cli 0.0.0.666__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 (158) hide show
  1. ara_cli/__init__.py +3 -0
  2. ara_cli/__main__.py +72 -0
  3. ara_cli/ara_command_action.py +612 -0
  4. ara_cli/ara_command_parser.py +328 -0
  5. ara_cli/ara_config.py +146 -0
  6. ara_cli/artefact_autofix.py +477 -0
  7. ara_cli/artefact_creator.py +146 -0
  8. ara_cli/artefact_deleter.py +51 -0
  9. ara_cli/artefact_fuzzy_search.py +64 -0
  10. ara_cli/artefact_link_updater.py +76 -0
  11. ara_cli/artefact_lister.py +136 -0
  12. ara_cli/artefact_models/__init__.py +0 -0
  13. ara_cli/artefact_models/artefact_load.py +10 -0
  14. ara_cli/artefact_models/artefact_mapping.py +39 -0
  15. ara_cli/artefact_models/artefact_model.py +414 -0
  16. ara_cli/artefact_models/artefact_templates.py +224 -0
  17. ara_cli/artefact_models/businessgoal_artefact_model.py +134 -0
  18. ara_cli/artefact_models/capability_artefact_model.py +94 -0
  19. ara_cli/artefact_models/epic_artefact_model.py +170 -0
  20. ara_cli/artefact_models/example_artefact_model.py +49 -0
  21. ara_cli/artefact_models/feature_artefact_model.py +467 -0
  22. ara_cli/artefact_models/issue_artefact_model.py +78 -0
  23. ara_cli/artefact_models/keyfeature_artefact_model.py +127 -0
  24. ara_cli/artefact_models/serialize_helper.py +18 -0
  25. ara_cli/artefact_models/task_artefact_model.py +109 -0
  26. ara_cli/artefact_models/userstory_artefact_model.py +193 -0
  27. ara_cli/artefact_models/vision_artefact_model.py +171 -0
  28. ara_cli/artefact_reader.py +175 -0
  29. ara_cli/artefact_renamer.py +93 -0
  30. ara_cli/artefact_scan.py +86 -0
  31. ara_cli/chat.py +739 -0
  32. ara_cli/classifier.py +74 -0
  33. ara_cli/codefusionretriever.py +53 -0
  34. ara_cli/codehierachieretriever.py +37 -0
  35. ara_cli/commandline_completer.py +42 -0
  36. ara_cli/directory_navigator.py +74 -0
  37. ara_cli/file_classifier.py +100 -0
  38. ara_cli/file_lister.py +54 -0
  39. ara_cli/filename_validator.py +4 -0
  40. ara_cli/list_filter.py +148 -0
  41. ara_cli/output_suppressor.py +17 -0
  42. ara_cli/prompt_chat.py +30 -0
  43. ara_cli/prompt_extractor.py +211 -0
  44. ara_cli/prompt_handler.py +464 -0
  45. ara_cli/prompt_rag.py +187 -0
  46. ara_cli/run_file_lister.py +69 -0
  47. ara_cli/tag_extractor.py +67 -0
  48. ara_cli/template_manager.py +151 -0
  49. ara_cli/templates/agile.artefacts +171 -0
  50. ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +27 -0
  51. ara_cli/templates/prompt-modules/blueprints/empty.blueprint.md +0 -0
  52. ara_cli/templates/prompt-modules/blueprints/task_todo_list_C4_architecture_analysis.blueprint.md +32 -0
  53. ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +30 -0
  54. ara_cli/templates/prompt-modules/commands/architecture_C4_analysis.commands.md +37 -0
  55. ara_cli/templates/prompt-modules/commands/architecture_radon_cc_score.commands.md +37 -0
  56. ara_cli/templates/prompt-modules/commands/architecture_radon_halstead_v.commands.md +32 -0
  57. ara_cli/templates/prompt-modules/commands/architecture_radon_maintainability_score.commands.md +82 -0
  58. ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +9 -0
  59. ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +17 -0
  60. ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +14 -0
  61. ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +102 -0
  62. ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +20 -0
  63. ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +13 -0
  64. ara_cli/templates/prompt-modules/commands/empty.commands.md +14 -0
  65. ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +20 -0
  66. ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +18 -0
  67. ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +43 -0
  68. ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +13 -0
  69. ara_cli/templates/prompt-modules/commands/refactoring.commands.md +15 -0
  70. ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +9 -0
  71. ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +15 -0
  72. ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +19 -0
  73. ara_cli/templates/prompt-modules/intentions/classify_task.intention.md +6 -0
  74. ara_cli/templates/prompt-modules/intentions/empty.intention.md +2 -0
  75. ara_cli/templates/prompt-modules/intentions/error_fixing.intention.md +9 -0
  76. ara_cli/templates/prompt-modules/intentions/feature_fix_steps_for_scenario.intention.md +2 -0
  77. ara_cli/templates/prompt-modules/intentions/feature_formulation.intention.md +2 -0
  78. ara_cli/templates/prompt-modules/intentions/feature_reverse_formulation_from_code.intention.md +2 -0
  79. ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation.intention.md +6 -0
  80. ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation_update.intention.md +8 -0
  81. ara_cli/templates/prompt-modules/intentions/feature_scenario_outline_extension.intention.md +2 -0
  82. ara_cli/templates/prompt-modules/intentions/feature_update_formulation.intention.md +5 -0
  83. ara_cli/templates/prompt-modules/intentions/fibonacci_example_implementation.intention.md +2 -0
  84. ara_cli/templates/prompt-modules/intentions/js_implementation_from_task_description.intention.md +2 -0
  85. ara_cli/templates/prompt-modules/intentions/js_steps_implementation.intention.md +4 -0
  86. ara_cli/templates/prompt-modules/intentions/python_cli_implementation_with_test.intention.md +6 -0
  87. ara_cli/templates/prompt-modules/intentions/python_code_understanding.intention.md +18 -0
  88. ara_cli/templates/prompt-modules/intentions/task_implementation.intention.md +2 -0
  89. ara_cli/templates/prompt-modules/intentions/task_prompt_control_by_status.intention.md +6 -0
  90. ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_number.intention.md +4 -0
  91. ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_status.intention.md +4 -0
  92. ara_cli/templates/prompt-modules/rules/architecture_analyst.rules.md +55 -0
  93. ara_cli/templates/prompt-modules/rules/code_analyst.rules.md +7 -0
  94. ara_cli/templates/prompt-modules/rules/empty.rules.md +2 -0
  95. ara_cli/templates/prompt-modules/rules/error_analyst.rules.md +13 -0
  96. ara_cli/templates/prompt-modules/rules/gherkin_expert.rules.md +15 -0
  97. ara_cli/templates/prompt-modules/rules/js_expert_developer.rules.md +9 -0
  98. ara_cli/templates/prompt-modules/rules/product_owner.rules.md +22 -0
  99. ara_cli/templates/prompt-modules/rules/python_behave.rules.md +13 -0
  100. ara_cli/templates/prompt-modules/rules/python_developer.rules.md +8 -0
  101. ara_cli/templates/specification_breakdown_files/template.concept.exploration.md +76 -0
  102. ara_cli/templates/specification_breakdown_files/template.concept.md +25 -0
  103. ara_cli/templates/specification_breakdown_files/template.customer.exploration.md +62 -0
  104. ara_cli/templates/specification_breakdown_files/template.customer.md +30 -0
  105. ara_cli/templates/specification_breakdown_files/template.persona.exploration.md +106 -0
  106. ara_cli/templates/specification_breakdown_files/template.persona.md +71 -0
  107. ara_cli/templates/specification_breakdown_files/template.step.exploration.md +0 -0
  108. ara_cli/templates/specification_breakdown_files/template.step.md +43 -0
  109. ara_cli/templates/specification_breakdown_files/template.technology.exploration.md +77 -0
  110. ara_cli/templates/specification_breakdown_files/template.technology.md +23 -0
  111. ara_cli/templates/template.businessgoal +10 -0
  112. ara_cli/templates/template.businessgoal.prompt_log.md +7 -0
  113. ara_cli/templates/template.capability +10 -0
  114. ara_cli/templates/template.capability.prompt_log.md +7 -0
  115. ara_cli/templates/template.epic +15 -0
  116. ara_cli/templates/template.epic.prompt_log.md +7 -0
  117. ara_cli/templates/template.example +6 -0
  118. ara_cli/templates/template.example.prompt_log.md +7 -0
  119. ara_cli/templates/template.feature +26 -0
  120. ara_cli/templates/template.feature.prompt_log.md +7 -0
  121. ara_cli/templates/template.issue +14 -0
  122. ara_cli/templates/template.issue.prompt_log.md +7 -0
  123. ara_cli/templates/template.keyfeature +15 -0
  124. ara_cli/templates/template.keyfeature.prompt_log.md +7 -0
  125. ara_cli/templates/template.steps.prompt_log.md +7 -0
  126. ara_cli/templates/template.task +6 -0
  127. ara_cli/templates/template.task.prompt_log.md +7 -0
  128. ara_cli/templates/template.userstory +17 -0
  129. ara_cli/templates/template.userstory.prompt_log.md +7 -0
  130. ara_cli/templates/template.vision +14 -0
  131. ara_cli/templates/template.vision.prompt_log.md +7 -0
  132. ara_cli/update_config_prompt.py +123 -0
  133. ara_cli/version.py +2 -0
  134. ara_cli-0.0.0.666.dist-info/METADATA +16 -0
  135. ara_cli-0.0.0.666.dist-info/RECORD +158 -0
  136. ara_cli-0.0.0.666.dist-info/WHEEL +5 -0
  137. ara_cli-0.0.0.666.dist-info/entry_points.txt +2 -0
  138. ara_cli-0.0.0.666.dist-info/top_level.txt +2 -0
  139. tests/__init__.py +0 -0
  140. tests/test_ara_command_action.py +692 -0
  141. tests/test_ara_config.py +59 -0
  142. tests/test_artefact_autofix.py +617 -0
  143. tests/test_artefact_fuzzy_search.py +32 -0
  144. tests/test_artefact_link_updater.py +48 -0
  145. tests/test_artefact_lister.py +631 -0
  146. tests/test_artefact_reader.py +16 -0
  147. tests/test_artefact_renamer.py +81 -0
  148. tests/test_artefact_scan.py +189 -0
  149. tests/test_chat.py +1070 -0
  150. tests/test_classifier.py +69 -0
  151. tests/test_directory_navigator.py +7 -0
  152. tests/test_file_classifier.py +271 -0
  153. tests/test_file_creator.py +60 -0
  154. tests/test_file_lister.py +122 -0
  155. tests/test_list_filter.py +205 -0
  156. tests/test_tag_extractor.py +83 -0
  157. tests/test_template_manager.py +106 -0
  158. tests/test_update_config_prompt.py +159 -0
ara_cli/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .version import __version__
2
+
3
+ whitelisted_commands = ["RERUN", "SEND", "EXTRACT", "LOAD_IMAGE", "CHOOSE_MODEL", "CURRENT_MODEL", "LIST_MODELS"]
ara_cli/__main__.py ADDED
@@ -0,0 +1,72 @@
1
+ # PYTHON_ARGCOMPLETE_OK
2
+ from ara_cli.ara_command_parser import action_parser
3
+ from ara_cli.version import __version__
4
+ from ara_cli.ara_command_action import (
5
+ create_action,
6
+ delete_action,
7
+ rename_action,
8
+ list_action,
9
+ list_tags_action,
10
+ prompt_action,
11
+ chat_action,
12
+ template_action,
13
+ fetch_templates_action,
14
+ read_action,
15
+ reconnect_action,
16
+ read_status_action,
17
+ read_user_action,
18
+ set_status_action,
19
+ set_user_action,
20
+ classifier_directory_action,
21
+ scan_action,
22
+ autofix_action
23
+ )
24
+ import argcomplete
25
+ import sys
26
+
27
+
28
+ def define_action_mapping():
29
+ return {
30
+ "create": create_action,
31
+ "delete": delete_action,
32
+ "rename": rename_action,
33
+ "list": list_action,
34
+ "list-tags": list_tags_action,
35
+ "prompt": prompt_action,
36
+ "chat": chat_action,
37
+ "template": template_action,
38
+ "fetch-templates": fetch_templates_action,
39
+ "read": read_action,
40
+ "reconnect": reconnect_action,
41
+ "read-status": read_status_action,
42
+ "read-user": read_user_action,
43
+ "set-status": set_status_action,
44
+ "set-user": set_user_action,
45
+ "classifier-directory": classifier_directory_action,
46
+ "scan": scan_action,
47
+ "autofix": autofix_action
48
+ }
49
+
50
+
51
+ def handle_invalid_action(args):
52
+ sys.exit("Invalid action provided. Type ara -h for help")
53
+
54
+
55
+ def cli():
56
+ parser = action_parser()
57
+ parser.add_argument('-v', '--version', action='version', version=f'%(prog)s {__version__}')
58
+
59
+ action_mapping = define_action_mapping()
60
+
61
+ argcomplete.autocomplete(parser)
62
+
63
+ args = parser.parse_args()
64
+ if not hasattr(args, 'action') or not args.action:
65
+ parser.print_help()
66
+ return
67
+ action = action_mapping.get(args.action, handle_invalid_action)
68
+ action(args)
69
+
70
+
71
+ if __name__ == "__main__":
72
+ cli()
@@ -0,0 +1,612 @@
1
+ from os.path import join
2
+ import os
3
+ import sys
4
+ import json
5
+ from ara_cli.output_suppressor import suppress_stdout
6
+ from ara_cli.artefact_fuzzy_search import suggest_close_name_matches
7
+ from . import whitelisted_commands
8
+
9
+
10
+ def check_validity(condition, error_message):
11
+ if not condition:
12
+ print(error_message)
13
+ sys.exit(1)
14
+
15
+
16
+ def create_action(args):
17
+ from ara_cli.artefact_creator import ArtefactCreator
18
+ from ara_cli.classifier import Classifier
19
+ from ara_cli.filename_validator import is_valid_filename
20
+ from ara_cli.template_manager import SpecificationBreakdownAspects
21
+ from ara_cli.artefact_reader import ArtefactReader
22
+ from ara_cli.artefact_fuzzy_search import find_closest_rule
23
+
24
+ check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
25
+ check_validity(is_valid_filename(args.parameter), "Invalid filename provided. Please provide a valid filename.")
26
+
27
+ def handle_parent_arguments(args):
28
+ parent_classifier = args.parent_classifier if hasattr(args, "parent_classifier") else None
29
+ parent_name = args.parent_name if hasattr(args, "parent_name") else None
30
+ rule = args.rule if hasattr(args, 'rule') else None
31
+ invalid_classifier_message = "Invalid parent classifier provided. Please provide a valid classifier"
32
+ invalid_name_message = "Invalid filename provided for parent. Please provide a valid filename."
33
+ if parent_classifier and parent_name and rule:
34
+ check_validity(Classifier.is_valid_classifier(parent_classifier), invalid_classifier_message)
35
+ check_validity(is_valid_filename(parent_name), invalid_name_message)
36
+ parent_artefact = ArtefactReader.read_artefact(artefact_name=parent_name, classifier=parent_classifier)
37
+ rule = find_closest_rule(parent_artefact, rule)
38
+ return parent_classifier, parent_name, rule
39
+ if parent_classifier and parent_name:
40
+ check_validity(Classifier.is_valid_classifier(parent_classifier), invalid_classifier_message)
41
+ check_validity(is_valid_filename(parent_name), invalid_name_message)
42
+ return parent_classifier, parent_name, rule
43
+ return None, None, None
44
+
45
+ def handle_aspect_creation(args):
46
+ aspect = args.aspect if hasattr(args, "aspect") else None
47
+ if args.parameter and args.classifier and aspect:
48
+ sba = SpecificationBreakdownAspects()
49
+ try:
50
+ sba.create(args.parameter, args.classifier, aspect)
51
+ return True
52
+ except ValueError as ve:
53
+ print(f"Error: {ve}")
54
+ sys.exit(1)
55
+ return False
56
+
57
+ parent_classifier, parent_name, rule = handle_parent_arguments(args)
58
+ if handle_aspect_creation(args):
59
+ return
60
+
61
+ artefact_creator = ArtefactCreator()
62
+ artefact_creator.run(args.parameter, args.classifier, parent_classifier, parent_name, rule)
63
+
64
+
65
+ def delete_action(args):
66
+ from ara_cli.artefact_deleter import ArtefactDeleter
67
+
68
+ artefact_deleter = ArtefactDeleter()
69
+ artefact_deleter.delete(args.parameter, args.classifier, args.force)
70
+
71
+
72
+ def rename_action(args):
73
+ from ara_cli.artefact_renamer import ArtefactRenamer
74
+ from ara_cli.classifier import Classifier
75
+ from ara_cli.filename_validator import is_valid_filename
76
+
77
+ check_validity(is_valid_filename(args.parameter), "Invalid filename provided. Please provide a valid filename.")
78
+ check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
79
+ check_validity(is_valid_filename(args.aspect), "Invalid new filename provided. Please provide a valid filename.")
80
+
81
+ artefact_renamer = ArtefactRenamer()
82
+ artefact_renamer.rename(args.parameter, args.aspect, args.classifier)
83
+
84
+
85
+ def list_action(args):
86
+ from ara_cli.artefact_lister import ArtefactLister
87
+ from ara_cli.list_filter import ListFilter
88
+
89
+ branch_classifier, branch_artefact_name = args.branch_args
90
+ children_classifier, children_artefact_name = args.children_args
91
+ data_classifier, data_artefact_name = args.data_args
92
+
93
+ artefact_lister = ArtefactLister()
94
+
95
+ list_filter = ListFilter(
96
+ include_content=args.include_content,
97
+ exclude_content=args.exclude_content,
98
+ include_extension=args.include_extension,
99
+ exclude_extension=args.exclude_extension,
100
+ include_tags=args.include_tags,
101
+ exclude_tags=args.exclude_tags
102
+ )
103
+
104
+ if branch_classifier and branch_artefact_name:
105
+ artefact_lister.list_branch(
106
+ classifier=branch_classifier,
107
+ artefact_name=branch_artefact_name,
108
+ list_filter=list_filter
109
+ )
110
+ return
111
+
112
+ if children_classifier and children_artefact_name:
113
+ artefact_lister.list_children(
114
+ classifier=children_classifier,
115
+ artefact_name=children_artefact_name,
116
+ list_filter=list_filter
117
+ )
118
+ return
119
+
120
+ if data_classifier and data_artefact_name:
121
+ artefact_lister.list_data(
122
+ classifier=data_classifier,
123
+ artefact_name=data_artefact_name,
124
+ list_filter=list_filter
125
+ )
126
+ return
127
+
128
+ if (args.tags):
129
+ artefact_lister.list_files(tags=args.tags, list_filter=list_filter)
130
+ return
131
+ artefact_lister.list_files(list_filter=list_filter)
132
+
133
+
134
+ def list_tags_action(args):
135
+ from ara_cli.tag_extractor import TagExtractor
136
+ from ara_cli.list_filter import ListFilter
137
+
138
+ list_filter = ListFilter(
139
+ include_extension=args.include_classifier,
140
+ exclude_extension=args.exclude_classifier,
141
+ )
142
+
143
+ tag_extractor = TagExtractor()
144
+ tags = tag_extractor.extract_tags(
145
+ filtered_extra_column=getattr(args, "filtered_extra_column", False),
146
+ list_filter=list_filter
147
+ )
148
+
149
+ if args.json:
150
+ output = json.dumps({"tags": tags})
151
+ print(output)
152
+ return
153
+
154
+ output = "\n".join(f"- {tag}" for tag in tags)
155
+ print(output)
156
+
157
+
158
+ def prompt_action(args):
159
+ from ara_cli.classifier import Classifier
160
+ from ara_cli.filename_validator import is_valid_filename
161
+
162
+ check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
163
+ check_validity(is_valid_filename(args.parameter), "Invalid filename provided. Please provide a valid filename.")
164
+
165
+ classifier = args.classifier
166
+ param = args.parameter
167
+ init = args.steps
168
+
169
+ def handle_init():
170
+ from ara_cli.prompt_handler import initialize_prompt_templates
171
+ initialize_prompt_templates(classifier, param)
172
+
173
+ def handle_init_rag():
174
+ from ara_cli.prompt_handler import initialize_prompt_templates
175
+ from ara_cli.prompt_rag import search_and_add_relevant_files_to_prompt_givens
176
+ initialize_prompt_templates(classifier, param)
177
+ search_and_add_relevant_files_to_prompt_givens(classifier, param)
178
+
179
+ def handle_load():
180
+ from ara_cli.prompt_handler import load_selected_prompt_templates
181
+ load_selected_prompt_templates(classifier, param)
182
+
183
+ def handle_send():
184
+ from ara_cli.prompt_handler import create_and_send_custom_prompt
185
+ create_and_send_custom_prompt(classifier, param)
186
+
187
+ def handle_load_and_send():
188
+ from ara_cli.prompt_handler import load_selected_prompt_templates, create_and_send_custom_prompt
189
+ load_selected_prompt_templates(classifier, param)
190
+ create_and_send_custom_prompt(classifier, param)
191
+
192
+ def handle_extract():
193
+ from ara_cli.prompt_extractor import extract_and_save_prompt_results
194
+ from ara_cli.update_config_prompt import update_artefact_config_prompt_files
195
+ extract_and_save_prompt_results(classifier, param)
196
+ print(f"automatic update after extract")
197
+ update_artefact_config_prompt_files(classifier, param, automatic_update=True)
198
+
199
+ def handle_chat():
200
+ from ara_cli.prompt_chat import initialize_prompt_chat_mode
201
+ chat_name = args.chat_name
202
+ reset = args.reset
203
+ output_mode = args.output_mode
204
+ append_strings = args.append
205
+ restricted = args.restricted
206
+ initialize_prompt_chat_mode(classifier, param, chat_name, reset=reset, output_mode=output_mode, append_strings=append_strings, restricted=restricted)
207
+
208
+ def handle_update():
209
+ from ara_cli.update_config_prompt import update_artefact_config_prompt_files
210
+ update_artefact_config_prompt_files(classifier, param, automatic_update=True)
211
+
212
+ command_dispatcher = {
213
+ 'init': handle_init,
214
+ 'init-rag': handle_init_rag,
215
+ 'load': handle_load,
216
+ 'send': handle_send,
217
+ 'load-and-send': handle_load_and_send,
218
+ 'extract': handle_extract,
219
+ 'chat': handle_chat,
220
+ 'update': handle_update,
221
+ }
222
+
223
+ if init in command_dispatcher:
224
+ command_dispatcher[init]()
225
+ else:
226
+ raise ValueError(f"Unknown command '{init}' provided.")
227
+
228
+
229
+ def chat_action(args):
230
+ from ara_cli.chat import Chat
231
+
232
+ reset = args.reset
233
+ output_mode = args.output_mode
234
+ append_strings = args.append
235
+ restricted = args.restricted
236
+
237
+ chat_name = "chat"
238
+ if args.chat_name:
239
+ chat_name = args.chat_name
240
+ cwd = os.getcwd()
241
+ chat_file_path = join(cwd, chat_name)
242
+
243
+ with suppress_stdout(output_mode):
244
+ chat = Chat(chat_file_path, reset=reset) if not restricted else Chat(chat_file_path, reset=reset, enable_commands=whitelisted_commands)
245
+
246
+ if append_strings:
247
+ chat.append_strings(append_strings)
248
+
249
+ if output_mode:
250
+ chat.start_non_interactive()
251
+ return
252
+ chat.start()
253
+
254
+
255
+ def template_action(args):
256
+ from ara_cli.classifier import Classifier
257
+ from ara_cli.template_manager import TemplatePathManager
258
+
259
+ check_validity(Classifier.is_valid_classifier(args.classifier), "Invalid classifier provided. Please provide a valid classifier.")
260
+
261
+ template_manager = TemplatePathManager()
262
+ content = template_manager.get_template_content(args.classifier)
263
+
264
+ print(content)
265
+
266
+
267
+ def fetch_templates_action(args):
268
+ import shutil
269
+ from ara_cli.ara_config import ConfigManager
270
+ from ara_cli.template_manager import TemplatePathManager
271
+
272
+ config = ConfigManager().get_config()
273
+ prompt_templates_dir = config.local_prompt_templates_dir
274
+ template_base_path = TemplatePathManager.get_template_base_path()
275
+ global_prompt_templates_path = join(template_base_path, "prompt-modules")
276
+
277
+ subdirs = ["commands", "rules", "intentions", "blueprints"]
278
+
279
+ os.makedirs(join(prompt_templates_dir, "global-prompt-modules"), exist_ok=True)
280
+ for subdir in subdirs:
281
+ target_dir = join(prompt_templates_dir, "global-prompt-modules", subdir)
282
+ source_dir = join(global_prompt_templates_path, subdir)
283
+ os.makedirs(target_dir, exist_ok=True)
284
+ for item in os.listdir(source_dir):
285
+ source = join(source_dir, item)
286
+ target = join(target_dir, item)
287
+ shutil.copy2(source, target)
288
+
289
+ custom_prompt_templates_subdir = config.custom_prompt_templates_subdir
290
+ local_prompt_modules_dir = join(prompt_templates_dir, custom_prompt_templates_subdir)
291
+ os.makedirs(local_prompt_modules_dir, exist_ok=True)
292
+ for subdir in subdirs:
293
+ os.makedirs(join(local_prompt_modules_dir, subdir), exist_ok=True)
294
+
295
+
296
+ def read_action(args):
297
+ from ara_cli.artefact_reader import ArtefactReader
298
+ from ara_cli.file_classifier import FileClassifier
299
+
300
+ classifier = args.classifier
301
+ artefact_name = args.parameter
302
+ read_mode = args.read_mode
303
+
304
+ file_classifier = FileClassifier(os)
305
+ classified_artefacts = ArtefactReader.read_artefacts()
306
+ artefacts = classified_artefacts.get(classifier, [])
307
+ all_artefact_names = [a.title for a in artefacts]
308
+
309
+ if artefact_name not in all_artefact_names:
310
+ suggest_close_name_matches(
311
+ artefact_name,
312
+ all_artefact_names
313
+ )
314
+ return
315
+
316
+ target_artefact = next(filter(
317
+ lambda x: x.title == artefact_name, artefacts
318
+ ))
319
+
320
+ artefacts_by_classifier = {classifier: []}
321
+
322
+ match read_mode:
323
+ case "branch":
324
+ ArtefactReader.step_through_value_chain(
325
+ artefact_name=artefact_name,
326
+ classifier=classifier,
327
+ artefacts_by_classifier=artefacts_by_classifier,
328
+ classified_artefacts=classified_artefacts
329
+ )
330
+ file_classifier.print_classified_files(artefacts_by_classifier, print_content=True)
331
+ case "children":
332
+ artefacts = ArtefactReader.find_children(
333
+ artefact_name=artefact_name,
334
+ classifier=classifier,
335
+ classified_artefacts=classified_artefacts
336
+ )
337
+ file_classifier.print_classified_files(
338
+ files_by_classifier=artefacts,
339
+ print_content=True
340
+ )
341
+ case _:
342
+ artefacts_by_classifier[classifier].append(target_artefact)
343
+ file_classifier.print_classified_files(artefacts_by_classifier, print_content=True)
344
+
345
+
346
+ def reconnect_action(args):
347
+ from ara_cli.artefact_models.artefact_load import artefact_from_content
348
+ from ara_cli.artefact_models.artefact_model import Contribution
349
+ from ara_cli.artefact_reader import ArtefactReader
350
+ from ara_cli.artefact_fuzzy_search import find_closest_rule
351
+
352
+ classifier = args.classifier
353
+ artefact_name = args.parameter
354
+ parent_classifier = args.parent_classifier
355
+ parent_name = args.parent_name
356
+ rule = args.rule if hasattr(args, 'rule') else None
357
+
358
+ read_error_message = f"Could not connect {classifier} '{artefact_name}' to {parent_classifier} '{parent_name}'"
359
+
360
+ feedback_message = f"Updated contribution of {classifier} '{artefact_name}' to {parent_classifier} '{parent_name}'"
361
+
362
+ content, artefact_info = ArtefactReader.read_artefact_data(
363
+ artefact_name=artefact_name,
364
+ classifier=classifier
365
+ )
366
+ if not content:
367
+ print(read_error_message)
368
+ return
369
+
370
+ parent_content, parent_info = ArtefactReader.read_artefact_data(
371
+ artefact_name=parent_name,
372
+ classifier=parent_classifier
373
+ )
374
+ if not parent_content:
375
+ print(read_error_message)
376
+ return
377
+
378
+ artefact = artefact_from_content(
379
+ content=content,
380
+ )
381
+ artefact._file_path = artefact_info["file_path"]
382
+
383
+ parent = artefact_from_content(
384
+ content=parent_content
385
+ )
386
+
387
+ contribution = Contribution(
388
+ artefact_name=parent.title,
389
+ classifier=parent.artefact_type
390
+ )
391
+
392
+ if rule:
393
+ try:
394
+ closest_rule = find_closest_rule(parent, rule)
395
+ contribution.rule = closest_rule
396
+ feedback_message += f" using rule '{closest_rule}'"
397
+ except TypeError as e:
398
+ print(f"{type(e).__name__}:", e)
399
+ exit(1)
400
+
401
+ artefact.contribution = contribution
402
+ with open(artefact.file_path, 'w', encoding='utf-8') as file:
403
+ artefact_content = artefact.serialize()
404
+ file.write(artefact_content)
405
+
406
+ print(feedback_message + ".")
407
+
408
+
409
+ def read_status_action(args):
410
+ from ara_cli.file_classifier import FileClassifier
411
+ from ara_cli.artefact_models.artefact_load import artefact_from_content
412
+
413
+ classifier = args.classifier
414
+ artefact_name = args.parameter
415
+
416
+ file_classifier = FileClassifier(os)
417
+ artefact_info = file_classifier.classify_files()
418
+ artefact_info_dicts = artefact_info.get(classifier, [])
419
+
420
+ all_artefact_names = [artefact_info["title"] for artefact_info in artefact_info_dicts]
421
+ if artefact_name not in all_artefact_names:
422
+ suggest_close_name_matches(artefact_name, all_artefact_names)
423
+ return
424
+
425
+ artefact_info = next(filter(
426
+ lambda x: x["title"] == artefact_name, artefact_info_dicts
427
+ ))
428
+
429
+ with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
430
+ content = file.read()
431
+ artefact = artefact_from_content(content)
432
+
433
+ status = artefact.status
434
+
435
+ if not status:
436
+ print("No status found")
437
+ return
438
+ print(status)
439
+
440
+
441
+ def read_user_action(args):
442
+ from ara_cli.artefact_models.artefact_load import artefact_from_content
443
+ from ara_cli.file_classifier import FileClassifier
444
+
445
+ classifier = args.classifier
446
+ artefact_name = args.parameter
447
+
448
+ file_classifier = FileClassifier(os)
449
+ artefact_info = file_classifier.classify_files()
450
+ artefact_info_dicts = artefact_info.get(classifier, [])
451
+
452
+ all_artefact_names = [artefact_info["title"] for artefact_info in artefact_info_dicts]
453
+ if artefact_name not in all_artefact_names:
454
+ suggest_close_name_matches(artefact_name, all_artefact_names)
455
+ return
456
+
457
+ artefact_info = next(filter(
458
+ lambda x: x["title"] == artefact_name, artefact_info_dicts
459
+ ))
460
+
461
+ with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
462
+ content = file.read()
463
+ artefact = artefact_from_content(content)
464
+
465
+ user_tags = artefact.users
466
+
467
+ if not user_tags:
468
+ print("No user found")
469
+ return
470
+ for tag in user_tags:
471
+ print(f" - {tag}")
472
+
473
+
474
+ def set_status_action(args):
475
+ from ara_cli.artefact_models.artefact_model import ALLOWED_STATUS_VALUES
476
+ from ara_cli.artefact_models.artefact_load import artefact_from_content
477
+ from ara_cli.file_classifier import FileClassifier
478
+
479
+ status_tags = ALLOWED_STATUS_VALUES
480
+
481
+ classifier = args.classifier
482
+ artefact_name = args.parameter
483
+ new_status = args.new_status
484
+
485
+ if new_status.startswith('@'):
486
+ new_status = new_status.lstrip('@')
487
+
488
+ check_validity(new_status in status_tags, "Invalid status provided. Please provide a valid status.")
489
+
490
+ file_classifier = FileClassifier(os)
491
+ classified_artefacts_info = file_classifier.classify_files()
492
+ classified_artefact_dict = classified_artefacts_info.get(classifier, [])
493
+ all_artefact_names = [artefact_info["title"] for artefact_info in classified_artefact_dict]
494
+
495
+ if artefact_name not in all_artefact_names:
496
+ suggest_close_name_matches(artefact_name, all_artefact_names)
497
+ return
498
+
499
+ artefact_info = next(filter(
500
+ lambda x: x["title"] == artefact_name, classified_artefact_dict
501
+ ))
502
+
503
+ with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
504
+ content = file.read()
505
+ artefact = artefact_from_content(content)
506
+
507
+ artefact.status = new_status
508
+
509
+ serialized_content = artefact.serialize()
510
+ with open(f"{artefact_info['file_path']}", 'w', encoding='utf-8') as file:
511
+ file.write(serialized_content)
512
+
513
+ print(f"Status of task '{artefact_name}' has been updated to '{new_status}'.")
514
+
515
+
516
+ def set_user_action(args):
517
+ from ara_cli.file_classifier import FileClassifier
518
+ from ara_cli.artefact_models.artefact_load import artefact_from_content
519
+
520
+ classifier = args.classifier
521
+ artefact_name = args.parameter
522
+ new_user = args.new_user
523
+
524
+ if new_user.startswith('@'):
525
+ new_user = new_user.lstrip('@')
526
+
527
+ file_classifier = FileClassifier(os)
528
+ classified_artefacts_info = file_classifier.classify_files()
529
+ classified_artefact_dict = classified_artefacts_info.get(classifier, [])
530
+ all_artefact_names = [artefact_info["title"] for artefact_info in classified_artefact_dict]
531
+
532
+ if artefact_name not in all_artefact_names:
533
+ suggest_close_name_matches(artefact_name, all_artefact_names)
534
+ return
535
+
536
+ artefact_info = next(filter(
537
+ lambda x: x["title"] == artefact_name, classified_artefact_dict
538
+ ))
539
+
540
+ with open(artefact_info["file_path"], 'r', encoding='utf-8') as file:
541
+ content = file.read()
542
+ artefact = artefact_from_content(content)
543
+
544
+ artefact.users = [new_user]
545
+
546
+ serialized_content = artefact.serialize()
547
+
548
+ with open(artefact_info["file_path"], 'w', encoding='utf-8') as file:
549
+ file.write(serialized_content)
550
+
551
+ print(f"User of task '{artefact_name}' has been updated to '{new_user}'.")
552
+
553
+
554
+ def classifier_directory_action(args):
555
+ from ara_cli.classifier import Classifier
556
+
557
+ classifier = args.classifier
558
+ subdirectory = Classifier.get_sub_directory(classifier)
559
+ print(subdirectory)
560
+
561
+
562
+ def scan_action(args):
563
+ from ara_cli.file_classifier import FileClassifier
564
+ from ara_cli.artefact_scan import find_invalid_files, show_results
565
+ import os
566
+
567
+ classified_artefact_info = FileClassifier(os).classify_files()
568
+ invalid_artefacts = {}
569
+ for classifier in classified_artefact_info:
570
+ invalid = find_invalid_files(classified_artefact_info, classifier)
571
+ if invalid:
572
+ invalid_artefacts[classifier] = invalid
573
+ show_results(invalid_artefacts)
574
+
575
+
576
+ def autofix_action(args):
577
+ from ara_cli.artefact_autofix import parse_report, apply_autofix, read_report_file
578
+ from ara_cli.file_classifier import FileClassifier
579
+
580
+ # If the user passes --non-deterministic, only_deterministic_fix becomes False.
581
+ # If the user passes --deterministic, only_non_deterministic_fix becomes False.
582
+ # If no flags are passed, both are True, and all fixes are attempted.
583
+ run_deterministic = not args.non_deterministic
584
+ run_non_deterministic = not args.deterministic
585
+
586
+ content = read_report_file()
587
+ if not content:
588
+ return False
589
+
590
+ issues = parse_report(content)
591
+ if not issues:
592
+ print("No issues found in the report. Nothing to fix.")
593
+ return
594
+
595
+ file_classifier = FileClassifier(os)
596
+ classified_artefact_info = file_classifier.classify_files()
597
+
598
+ # print("\nStarting autofix process...")
599
+ for classifier, files in issues.items():
600
+ print(f"\nClassifier: {classifier}")
601
+ for file_path, reason in files:
602
+ apply_autofix(
603
+ file_path,
604
+ classifier,
605
+ reason,
606
+ single_pass=args.single_pass,
607
+ deterministic=run_deterministic,
608
+ non_deterministic=run_non_deterministic,
609
+ classified_artefact_info=classified_artefact_info
610
+ )
611
+
612
+ print("\nAutofix process completed. Please review the changes.")