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.
- ara_cli/__init__.py +3 -0
- ara_cli/__main__.py +72 -0
- ara_cli/ara_command_action.py +612 -0
- ara_cli/ara_command_parser.py +328 -0
- ara_cli/ara_config.py +146 -0
- ara_cli/artefact_autofix.py +477 -0
- ara_cli/artefact_creator.py +146 -0
- ara_cli/artefact_deleter.py +51 -0
- ara_cli/artefact_fuzzy_search.py +64 -0
- ara_cli/artefact_link_updater.py +76 -0
- ara_cli/artefact_lister.py +136 -0
- ara_cli/artefact_models/__init__.py +0 -0
- ara_cli/artefact_models/artefact_load.py +10 -0
- ara_cli/artefact_models/artefact_mapping.py +39 -0
- ara_cli/artefact_models/artefact_model.py +414 -0
- ara_cli/artefact_models/artefact_templates.py +224 -0
- ara_cli/artefact_models/businessgoal_artefact_model.py +134 -0
- ara_cli/artefact_models/capability_artefact_model.py +94 -0
- ara_cli/artefact_models/epic_artefact_model.py +170 -0
- ara_cli/artefact_models/example_artefact_model.py +49 -0
- ara_cli/artefact_models/feature_artefact_model.py +467 -0
- ara_cli/artefact_models/issue_artefact_model.py +78 -0
- ara_cli/artefact_models/keyfeature_artefact_model.py +127 -0
- ara_cli/artefact_models/serialize_helper.py +18 -0
- ara_cli/artefact_models/task_artefact_model.py +109 -0
- ara_cli/artefact_models/userstory_artefact_model.py +193 -0
- ara_cli/artefact_models/vision_artefact_model.py +171 -0
- ara_cli/artefact_reader.py +175 -0
- ara_cli/artefact_renamer.py +93 -0
- ara_cli/artefact_scan.py +86 -0
- ara_cli/chat.py +739 -0
- ara_cli/classifier.py +74 -0
- ara_cli/codefusionretriever.py +53 -0
- ara_cli/codehierachieretriever.py +37 -0
- ara_cli/commandline_completer.py +42 -0
- ara_cli/directory_navigator.py +74 -0
- ara_cli/file_classifier.py +100 -0
- ara_cli/file_lister.py +54 -0
- ara_cli/filename_validator.py +4 -0
- ara_cli/list_filter.py +148 -0
- ara_cli/output_suppressor.py +17 -0
- ara_cli/prompt_chat.py +30 -0
- ara_cli/prompt_extractor.py +211 -0
- ara_cli/prompt_handler.py +464 -0
- ara_cli/prompt_rag.py +187 -0
- ara_cli/run_file_lister.py +69 -0
- ara_cli/tag_extractor.py +67 -0
- ara_cli/template_manager.py +151 -0
- ara_cli/templates/agile.artefacts +171 -0
- ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +27 -0
- ara_cli/templates/prompt-modules/blueprints/empty.blueprint.md +0 -0
- ara_cli/templates/prompt-modules/blueprints/task_todo_list_C4_architecture_analysis.blueprint.md +32 -0
- ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +30 -0
- ara_cli/templates/prompt-modules/commands/architecture_C4_analysis.commands.md +37 -0
- ara_cli/templates/prompt-modules/commands/architecture_radon_cc_score.commands.md +37 -0
- ara_cli/templates/prompt-modules/commands/architecture_radon_halstead_v.commands.md +32 -0
- ara_cli/templates/prompt-modules/commands/architecture_radon_maintainability_score.commands.md +82 -0
- ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +9 -0
- ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +17 -0
- ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +14 -0
- ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +102 -0
- ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +20 -0
- ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +13 -0
- ara_cli/templates/prompt-modules/commands/empty.commands.md +14 -0
- ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +20 -0
- ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +18 -0
- ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +43 -0
- ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +13 -0
- ara_cli/templates/prompt-modules/commands/refactoring.commands.md +15 -0
- ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +9 -0
- ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +15 -0
- ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +19 -0
- ara_cli/templates/prompt-modules/intentions/classify_task.intention.md +6 -0
- ara_cli/templates/prompt-modules/intentions/empty.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/error_fixing.intention.md +9 -0
- ara_cli/templates/prompt-modules/intentions/feature_fix_steps_for_scenario.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/feature_formulation.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/feature_reverse_formulation_from_code.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation.intention.md +6 -0
- ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation_update.intention.md +8 -0
- ara_cli/templates/prompt-modules/intentions/feature_scenario_outline_extension.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/feature_update_formulation.intention.md +5 -0
- ara_cli/templates/prompt-modules/intentions/fibonacci_example_implementation.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/js_implementation_from_task_description.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/js_steps_implementation.intention.md +4 -0
- ara_cli/templates/prompt-modules/intentions/python_cli_implementation_with_test.intention.md +6 -0
- ara_cli/templates/prompt-modules/intentions/python_code_understanding.intention.md +18 -0
- ara_cli/templates/prompt-modules/intentions/task_implementation.intention.md +2 -0
- ara_cli/templates/prompt-modules/intentions/task_prompt_control_by_status.intention.md +6 -0
- ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_number.intention.md +4 -0
- ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_status.intention.md +4 -0
- ara_cli/templates/prompt-modules/rules/architecture_analyst.rules.md +55 -0
- ara_cli/templates/prompt-modules/rules/code_analyst.rules.md +7 -0
- ara_cli/templates/prompt-modules/rules/empty.rules.md +2 -0
- ara_cli/templates/prompt-modules/rules/error_analyst.rules.md +13 -0
- ara_cli/templates/prompt-modules/rules/gherkin_expert.rules.md +15 -0
- ara_cli/templates/prompt-modules/rules/js_expert_developer.rules.md +9 -0
- ara_cli/templates/prompt-modules/rules/product_owner.rules.md +22 -0
- ara_cli/templates/prompt-modules/rules/python_behave.rules.md +13 -0
- ara_cli/templates/prompt-modules/rules/python_developer.rules.md +8 -0
- ara_cli/templates/specification_breakdown_files/template.concept.exploration.md +76 -0
- ara_cli/templates/specification_breakdown_files/template.concept.md +25 -0
- ara_cli/templates/specification_breakdown_files/template.customer.exploration.md +62 -0
- ara_cli/templates/specification_breakdown_files/template.customer.md +30 -0
- ara_cli/templates/specification_breakdown_files/template.persona.exploration.md +106 -0
- ara_cli/templates/specification_breakdown_files/template.persona.md +71 -0
- ara_cli/templates/specification_breakdown_files/template.step.exploration.md +0 -0
- ara_cli/templates/specification_breakdown_files/template.step.md +43 -0
- ara_cli/templates/specification_breakdown_files/template.technology.exploration.md +77 -0
- ara_cli/templates/specification_breakdown_files/template.technology.md +23 -0
- ara_cli/templates/template.businessgoal +10 -0
- ara_cli/templates/template.businessgoal.prompt_log.md +7 -0
- ara_cli/templates/template.capability +10 -0
- ara_cli/templates/template.capability.prompt_log.md +7 -0
- ara_cli/templates/template.epic +15 -0
- ara_cli/templates/template.epic.prompt_log.md +7 -0
- ara_cli/templates/template.example +6 -0
- ara_cli/templates/template.example.prompt_log.md +7 -0
- ara_cli/templates/template.feature +26 -0
- ara_cli/templates/template.feature.prompt_log.md +7 -0
- ara_cli/templates/template.issue +14 -0
- ara_cli/templates/template.issue.prompt_log.md +7 -0
- ara_cli/templates/template.keyfeature +15 -0
- ara_cli/templates/template.keyfeature.prompt_log.md +7 -0
- ara_cli/templates/template.steps.prompt_log.md +7 -0
- ara_cli/templates/template.task +6 -0
- ara_cli/templates/template.task.prompt_log.md +7 -0
- ara_cli/templates/template.userstory +17 -0
- ara_cli/templates/template.userstory.prompt_log.md +7 -0
- ara_cli/templates/template.vision +14 -0
- ara_cli/templates/template.vision.prompt_log.md +7 -0
- ara_cli/update_config_prompt.py +123 -0
- ara_cli/version.py +2 -0
- ara_cli-0.0.0.666.dist-info/METADATA +16 -0
- ara_cli-0.0.0.666.dist-info/RECORD +158 -0
- ara_cli-0.0.0.666.dist-info/WHEEL +5 -0
- ara_cli-0.0.0.666.dist-info/entry_points.txt +2 -0
- ara_cli-0.0.0.666.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/test_ara_command_action.py +692 -0
- tests/test_ara_config.py +59 -0
- tests/test_artefact_autofix.py +617 -0
- tests/test_artefact_fuzzy_search.py +32 -0
- tests/test_artefact_link_updater.py +48 -0
- tests/test_artefact_lister.py +631 -0
- tests/test_artefact_reader.py +16 -0
- tests/test_artefact_renamer.py +81 -0
- tests/test_artefact_scan.py +189 -0
- tests/test_chat.py +1070 -0
- tests/test_classifier.py +69 -0
- tests/test_directory_navigator.py +7 -0
- tests/test_file_classifier.py +271 -0
- tests/test_file_creator.py +60 -0
- tests/test_file_lister.py +122 -0
- tests/test_list_filter.py +205 -0
- tests/test_tag_extractor.py +83 -0
- tests/test_template_manager.py +106 -0
- tests/test_update_config_prompt.py +159 -0
ara_cli/__init__.py
ADDED
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.")
|