ara-cli 0.1.10.5__py3-none-any.whl → 0.1.13.3__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 +51 -6
- ara_cli/__main__.py +87 -75
- ara_cli/ara_command_action.py +95 -57
- ara_cli/ara_config.py +187 -128
- ara_cli/ara_subcommands/common.py +2 -2
- ara_cli/ara_subcommands/config.py +221 -0
- ara_cli/ara_subcommands/convert.py +43 -0
- ara_cli/ara_subcommands/fetch.py +41 -0
- ara_cli/ara_subcommands/fetch_agents.py +22 -0
- ara_cli/ara_subcommands/fetch_scripts.py +19 -0
- ara_cli/ara_subcommands/fetch_templates.py +15 -10
- ara_cli/ara_subcommands/list.py +97 -23
- ara_cli/artefact_autofix.py +115 -62
- ara_cli/artefact_converter.py +256 -0
- ara_cli/chat.py +283 -62
- ara_cli/chat_agent/__init__.py +0 -0
- ara_cli/chat_agent/agent_process_manager.py +155 -0
- ara_cli/chat_script_runner/__init__.py +0 -0
- ara_cli/chat_script_runner/script_completer.py +23 -0
- ara_cli/chat_script_runner/script_finder.py +41 -0
- ara_cli/chat_script_runner/script_lister.py +36 -0
- ara_cli/chat_script_runner/script_runner.py +36 -0
- ara_cli/chat_web_search/__init__.py +0 -0
- ara_cli/chat_web_search/web_search.py +263 -0
- ara_cli/commands/agent_run_command.py +98 -0
- ara_cli/commands/fetch_agents_command.py +106 -0
- ara_cli/commands/fetch_scripts_command.py +43 -0
- ara_cli/commands/fetch_templates_command.py +39 -0
- ara_cli/commands/fetch_templates_commands.py +39 -0
- ara_cli/commands/list_agents_command.py +39 -0
- ara_cli/completers.py +71 -35
- ara_cli/constants.py +2 -0
- ara_cli/directory_navigator.py +37 -4
- ara_cli/llm_utils.py +58 -0
- ara_cli/prompt_chat.py +20 -4
- ara_cli/prompt_extractor.py +47 -32
- ara_cli/template_loader.py +2 -1
- ara_cli/template_manager.py +52 -21
- ara_cli/templates/global-scripts/hello_global.py +1 -0
- ara_cli/templates/prompt-modules/commands/add_scenarios_for_new_behaviour.feature_creation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/align_feature_with_implementation_changes.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/analyze_codebase_and_plan_tasks.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/choose_best_parent_artefact.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/create_tasks_from_artefact_content.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/create_tests_for_uncovered_modules.test_generation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/derive_features_from_video_description.feature_creation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/describe_agent_capabilities.agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/empty.commands.md +2 -12
- ara_cli/templates/prompt-modules/commands/execute_scoped_todos_in_task.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/explain_single_file_purpose.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/extract_file_information_bullets.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/extract_general.commands.md +12 -0
- ara_cli/templates/prompt-modules/commands/extract_markdown.commands.md +11 -0
- ara_cli/templates/prompt-modules/commands/extract_python.commands.md +13 -0
- ara_cli/templates/prompt-modules/commands/feature_add_or_modifiy_specified_behavior.commands.md +36 -0
- ara_cli/templates/prompt-modules/commands/feature_generate_initial_specified_bevahior.commands.md +53 -0
- ara_cli/templates/prompt-modules/commands/fix_failing_behave_step_definitions.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/fix_failing_pytest_tests.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/general_instruction_policy.commands.md +47 -0
- ara_cli/templates/prompt-modules/commands/generate_and_fix_pytest_tests.test_generation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/prompt_template_tech_stack_transformer.commands.md +95 -0
- ara_cli/templates/prompt-modules/commands/python_bug_fixing_code.commands.md +34 -0
- ara_cli/templates/prompt-modules/commands/python_generate_code.commands.md +27 -0
- ara_cli/templates/prompt-modules/commands/python_refactoring_code.commands.md +39 -0
- ara_cli/templates/prompt-modules/commands/python_step_definitions_generation_and_fixing.commands.md +40 -0
- ara_cli/templates/prompt-modules/commands/python_unittest_generation_and_fixing.commands.md +48 -0
- ara_cli/templates/prompt-modules/commands/suggest_next_story_child_tasks.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/summarize_or_transcribe_media.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/update_feature_to_match_implementation.feature_creation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/update_user_story_with_requirements.interview_agent.commands.md +1 -0
- ara_cli/version.py +1 -1
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.13.3.dist-info}/METADATA +33 -1
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.13.3.dist-info}/RECORD +89 -43
- tests/test_ara_command_action.py +31 -19
- tests/test_ara_config.py +177 -90
- tests/test_artefact_autofix.py +170 -97
- tests/test_artefact_autofix_integration.py +495 -0
- tests/test_artefact_converter.py +357 -0
- tests/test_artefact_extraction.py +564 -0
- tests/test_chat.py +162 -126
- tests/test_chat_givens_images.py +603 -0
- tests/test_chat_script_runner.py +454 -0
- tests/test_llm_utils.py +164 -0
- tests/test_prompt_chat.py +343 -0
- tests/test_prompt_extractor.py +683 -0
- tests/test_web_search.py +467 -0
- ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -27
- ara_cli/templates/prompt-modules/blueprints/pytest_unittest_prompt.blueprint.md +0 -32
- ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -30
- ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -9
- ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -17
- ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -14
- ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -102
- ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -20
- ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -13
- ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -20
- ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -18
- ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -43
- ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -13
- ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -15
- ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -9
- ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -15
- ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -19
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.13.3.dist-info}/WHEEL +0 -0
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.13.3.dist-info}/entry_points.txt +0 -0
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.13.3.dist-info}/top_level.txt +0 -0
ara_cli/__init__.py
CHANGED
|
@@ -1,20 +1,65 @@
|
|
|
1
1
|
import warnings
|
|
2
2
|
from .error_handler import ErrorHandler
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
whitelisted_commands = [
|
|
5
|
+
"RERUN",
|
|
6
|
+
"SEND",
|
|
7
|
+
"EXTRACT",
|
|
8
|
+
"LOAD_IMAGE",
|
|
9
|
+
"CHOOSE_MODEL",
|
|
10
|
+
"CHOOSE_EXTRACTION_MODEL",
|
|
11
|
+
"CURRENT_MODEL",
|
|
12
|
+
"CURRENT_EXTRACTION_MODEL",
|
|
13
|
+
"LIST_MODELS",
|
|
14
|
+
]
|
|
7
15
|
|
|
8
16
|
error_handler = ErrorHandler()
|
|
9
17
|
|
|
10
18
|
|
|
11
19
|
# ANSI escape codes for coloring
|
|
12
|
-
YELLOW =
|
|
13
|
-
RESET =
|
|
20
|
+
YELLOW = "\033[93m"
|
|
21
|
+
RESET = "\033[0m"
|
|
14
22
|
|
|
15
23
|
|
|
16
24
|
def format_warning(message, category, *args, **kwargs):
|
|
17
|
-
return f
|
|
25
|
+
return f"{YELLOW}[WARNING] {category.__name__}: {message}{RESET}\n"
|
|
18
26
|
|
|
19
27
|
|
|
20
28
|
warnings.formatwarning = format_warning
|
|
29
|
+
|
|
30
|
+
### CHAT VALUES ###
|
|
31
|
+
|
|
32
|
+
CATEGORY_CHAT_CONTROL = "Chat control commands"
|
|
33
|
+
CATEGORY_LLM_CONTROL = "Language model controls"
|
|
34
|
+
CATEGORY_SCRIPT_CONTROL = "Script control commands"
|
|
35
|
+
CATEGORY_AGENT_CONTROL = "Agent control commands"
|
|
36
|
+
|
|
37
|
+
ROLE_PROMPT = "ara prompt"
|
|
38
|
+
ROLE_RESPONSE = "ara response"
|
|
39
|
+
|
|
40
|
+
INTRO = """/***************************************/
|
|
41
|
+
araarar
|
|
42
|
+
aa ara
|
|
43
|
+
aa aa aara
|
|
44
|
+
a araarar
|
|
45
|
+
a ar ar
|
|
46
|
+
aa ara
|
|
47
|
+
a a
|
|
48
|
+
a aa
|
|
49
|
+
a a
|
|
50
|
+
ar aa aa
|
|
51
|
+
(c) ara chat by talsen team
|
|
52
|
+
aa aa
|
|
53
|
+
aa a
|
|
54
|
+
a aa
|
|
55
|
+
aa
|
|
56
|
+
/***************************************/
|
|
57
|
+
Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat mode):"""
|
|
58
|
+
|
|
59
|
+
BINARY_TYPE_MAPPING = {
|
|
60
|
+
".png": "image/png",
|
|
61
|
+
".jpg": "image/jpeg",
|
|
62
|
+
".jpeg": "image/jpeg",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
DOCUMENT_TYPE_EXTENSIONS = [".docx", ".doc", ".odt", ".pdf"]
|
ara_cli/__main__.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import typer
|
|
2
|
-
import sys
|
|
3
2
|
import os
|
|
4
3
|
from typing import Optional
|
|
5
4
|
from os import getenv
|
|
6
|
-
from ara_cli.error_handler import AraError
|
|
7
5
|
from ara_cli.version import __version__
|
|
8
6
|
from ara_cli import error_handler
|
|
9
7
|
from ara_cli.ara_subcommands.create import register as register_create_cli
|
|
@@ -14,18 +12,29 @@ from ara_cli.ara_subcommands.list_tags import register as register_list_tags_cli
|
|
|
14
12
|
from ara_cli.ara_subcommands.prompt import register as register_prompt_cli
|
|
15
13
|
from ara_cli.ara_subcommands.chat import register as register_chat_cli
|
|
16
14
|
from ara_cli.ara_subcommands.template import register as register_template_cli
|
|
17
|
-
from ara_cli.ara_subcommands.fetch_templates import
|
|
15
|
+
from ara_cli.ara_subcommands.fetch_templates import (
|
|
16
|
+
register as register_fetch_templates_cli,
|
|
17
|
+
)
|
|
18
|
+
from ara_cli.ara_subcommands.fetch_scripts import register as register_fetch_scripts_cli
|
|
19
|
+
from ara_cli.ara_subcommands.fetch_agents import register as register_fetch_agents_cli
|
|
20
|
+
from ara_cli.ara_subcommands.fetch import register as register_fetch_cli
|
|
18
21
|
from ara_cli.ara_subcommands.read import register as register_read_cli
|
|
19
22
|
from ara_cli.ara_subcommands.reconnect import register as register_reconnect_cli
|
|
20
23
|
from ara_cli.ara_subcommands.read_status import register as register_read_status_cli
|
|
21
24
|
from ara_cli.ara_subcommands.read_user import register as register_read_user_cli
|
|
22
25
|
from ara_cli.ara_subcommands.set_status import register as register_set_status_cli
|
|
23
26
|
from ara_cli.ara_subcommands.set_user import register as register_set_user_cli
|
|
24
|
-
from ara_cli.ara_subcommands.classifier_directory import
|
|
27
|
+
from ara_cli.ara_subcommands.classifier_directory import (
|
|
28
|
+
register as register_classifier_directory_cli,
|
|
29
|
+
)
|
|
25
30
|
from ara_cli.ara_subcommands.scan import register as register_scan_cli
|
|
26
31
|
from ara_cli.ara_subcommands.autofix import register as register_autofix_cli
|
|
27
32
|
from ara_cli.ara_subcommands.extract import register as register_extract_cli
|
|
28
33
|
from ara_cli.ara_subcommands.load import register as register_load_cli
|
|
34
|
+
from ara_cli.ara_subcommands.config import register as register_config_cli
|
|
35
|
+
from ara_cli.ara_subcommands.convert import register as register_convert_cli
|
|
36
|
+
|
|
37
|
+
from ara_cli.directory_navigator import DirectoryNavigator
|
|
29
38
|
|
|
30
39
|
|
|
31
40
|
def version_callback(value: bool):
|
|
@@ -36,7 +45,7 @@ def version_callback(value: bool):
|
|
|
36
45
|
|
|
37
46
|
def is_debug_mode_enabled():
|
|
38
47
|
"""Check if debug mode is enabled via environment variable."""
|
|
39
|
-
return getenv(
|
|
48
|
+
return getenv("ARA_DEBUG", "").lower() in ("1", "true", "yes")
|
|
40
49
|
|
|
41
50
|
|
|
42
51
|
def configure_debug_mode(debug: bool, env_debug_mode: bool):
|
|
@@ -45,95 +54,74 @@ def configure_debug_mode(debug: bool, env_debug_mode: bool):
|
|
|
45
54
|
error_handler.debug_mode = True
|
|
46
55
|
|
|
47
56
|
|
|
48
|
-
def find_ara_directory_root():
|
|
49
|
-
"""Find the root ara directory by traversing up the directory tree."""
|
|
50
|
-
current_dir = os.getcwd()
|
|
51
|
-
|
|
52
|
-
# Check if we're already inside an ara directory structure
|
|
53
|
-
path_parts = current_dir.split(os.sep)
|
|
54
|
-
|
|
55
|
-
# Look for 'ara' in the path parts
|
|
56
|
-
if 'ara' in path_parts:
|
|
57
|
-
ara_index = path_parts.index('ara')
|
|
58
|
-
# Reconstruct path up to and including 'ara'
|
|
59
|
-
ara_root_parts = path_parts[:ara_index + 1]
|
|
60
|
-
potential_ara_root = os.sep.join(ara_root_parts)
|
|
61
|
-
if os.path.exists(potential_ara_root) and os.path.isdir(potential_ara_root):
|
|
62
|
-
return potential_ara_root
|
|
63
|
-
|
|
64
|
-
# If not inside ara directory, check current directory and parents
|
|
65
|
-
check_dir = current_dir
|
|
66
|
-
while check_dir != os.path.dirname(check_dir): # Stop at filesystem root
|
|
67
|
-
ara_path = os.path.join(check_dir, 'ara')
|
|
68
|
-
if os.path.exists(ara_path) and os.path.isdir(ara_path):
|
|
69
|
-
return ara_path
|
|
70
|
-
check_dir = os.path.dirname(check_dir)
|
|
71
|
-
|
|
72
|
-
return None
|
|
73
|
-
|
|
74
|
-
|
|
75
57
|
def check_ara_directory_exists():
|
|
76
58
|
"""Check if ara directory exists or if we're inside ara directory tree."""
|
|
77
|
-
return find_ara_directory_root() is not None
|
|
59
|
+
return DirectoryNavigator.find_ara_directory_root() is not None
|
|
78
60
|
|
|
79
61
|
|
|
80
62
|
def prompt_create_ara_directory():
|
|
81
63
|
"""Prompt user to create ara directory and create it if confirmed."""
|
|
82
64
|
# Print the prompt message
|
|
83
|
-
print(
|
|
84
|
-
|
|
65
|
+
print(
|
|
66
|
+
"No 'ara' directory found. Create one in the current directory? (Y/n)",
|
|
67
|
+
end=" ",
|
|
68
|
+
flush=True,
|
|
69
|
+
)
|
|
70
|
+
|
|
85
71
|
# Read user input
|
|
86
72
|
try:
|
|
87
73
|
response = input().strip()
|
|
88
74
|
except (EOFError, KeyboardInterrupt):
|
|
89
75
|
typer.echo("\nOperation cancelled.")
|
|
90
76
|
raise typer.Exit(1)
|
|
91
|
-
|
|
92
|
-
if response.lower() in (
|
|
77
|
+
|
|
78
|
+
if response.lower() in ("y", "yes", ""):
|
|
93
79
|
current_dir = os.getcwd()
|
|
94
|
-
ara_path = os.path.join(current_dir,
|
|
95
|
-
|
|
80
|
+
ara_path = os.path.join(current_dir, "ara")
|
|
81
|
+
|
|
96
82
|
# Create ara directory structure
|
|
97
83
|
subdirectories = [
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
84
|
+
"businessgoals",
|
|
85
|
+
"capabilities",
|
|
86
|
+
"epics",
|
|
87
|
+
"examples",
|
|
88
|
+
"features",
|
|
89
|
+
"keyfeatures",
|
|
90
|
+
"tasks",
|
|
91
|
+
"userstories",
|
|
92
|
+
"vision",
|
|
107
93
|
]
|
|
108
|
-
|
|
94
|
+
|
|
109
95
|
try:
|
|
110
96
|
# Create main ara directory
|
|
111
97
|
os.makedirs(ara_path, exist_ok=True)
|
|
112
|
-
|
|
98
|
+
|
|
113
99
|
# Create subdirectories for artefact types
|
|
114
100
|
for subdir in subdirectories:
|
|
115
101
|
os.makedirs(os.path.join(ara_path, subdir), exist_ok=True)
|
|
116
|
-
|
|
102
|
+
|
|
117
103
|
# Create .araconfig directory
|
|
118
|
-
araconfig_path = os.path.join(ara_path,
|
|
104
|
+
araconfig_path = os.path.join(ara_path, ".araconfig")
|
|
119
105
|
os.makedirs(araconfig_path, exist_ok=True)
|
|
120
|
-
|
|
106
|
+
|
|
121
107
|
# Create default ara_config.json using ConfigManager
|
|
122
108
|
from ara_cli.ara_config import ConfigManager, ARAconfig
|
|
123
|
-
|
|
124
|
-
|
|
109
|
+
|
|
110
|
+
config_file_path = os.path.join(araconfig_path, "ara_config.json")
|
|
111
|
+
|
|
125
112
|
# Reset ConfigManager to ensure clean state
|
|
126
113
|
ConfigManager.reset()
|
|
127
|
-
|
|
114
|
+
|
|
128
115
|
# Create default config and save it
|
|
129
116
|
default_config = ARAconfig()
|
|
130
117
|
from ara_cli.ara_config import save_data
|
|
118
|
+
|
|
131
119
|
save_data(config_file_path, default_config)
|
|
132
|
-
|
|
120
|
+
|
|
133
121
|
typer.echo(f"Created ara directory structure at {ara_path}")
|
|
134
122
|
typer.echo(f"Created default configuration at {config_file_path}")
|
|
135
123
|
return True
|
|
136
|
-
|
|
124
|
+
|
|
137
125
|
except OSError as e:
|
|
138
126
|
typer.echo(f"Error creating ara directory: {e}", err=True)
|
|
139
127
|
raise typer.Exit(1)
|
|
@@ -181,15 +169,16 @@ ara artefact handling examples:
|
|
|
181
169
|
> rename artefact and artefact data directory for e.g. a feature: ara rename feature {initial_feature_name} {new_feature_name}
|
|
182
170
|
> create additional templates for a specific aspect (valid aspects are: customer,
|
|
183
171
|
persona, concept, technology) related to an existing artefact like a feature: ara create feature {feature_name} aspect {aspect_name}
|
|
184
|
-
> list artefact data with .md file extension ara list
|
|
185
|
-
> list artefact data with .md and .json file extensions ara list
|
|
172
|
+
> list artefact data with .md file extension ara list {classifier} {artefact_name} --data --include-extension .md
|
|
173
|
+
> list artefact data with .md and .json file extensions ara list {classifier} {artefact_name} --data --include-extension .md .json
|
|
186
174
|
> list everything but userstories ara list --exclude-extension .userstory
|
|
187
175
|
> list all existing features: ara list --include-extension .feature
|
|
176
|
+
> list all artefacts of a specific classifier: ara list {classifier}
|
|
188
177
|
> list all child artefacts contributing value to a parent artefact: ara list --include-content "Contributes to {name_of_parent_artefact} {ara classifier_of_parent_artefact}"
|
|
189
178
|
> list tasks which contain 'example content' ara list --include-extension .task --include-content "example content"
|
|
190
|
-
> list children artefacts of a userstory ara list
|
|
191
|
-
> list parent artefacts of a userstory ara list
|
|
192
|
-
> list parent businessgoal artefact of a userstory ara list
|
|
179
|
+
> list children artefacts of a userstory ara list userstory {name_of_userstory} --children
|
|
180
|
+
> list parent artefacts of a userstory ara list userstory {name_of_userstory} --branch
|
|
181
|
+
> list parent businessgoal artefact of a userstory ara list userstory {name_of_userstory} --branch --include-extension .businessgoal
|
|
193
182
|
> print any artefact template for e.g. a feature file template in the terminal: ara template feature
|
|
194
183
|
|
|
195
184
|
ara prompt templates examples:
|
|
@@ -204,25 +193,32 @@ ara chat examples:
|
|
|
204
193
|
> load selected templates in config_prompt_templates.md for the task {task_name}: ara prompt load task {task_name}
|
|
205
194
|
> create and send configured prompt of the task {task_name} to the configured LLM: ara prompt send task {task_name}
|
|
206
195
|
> extract the selected LLM response in task.exploration.md and save to disk: ara prompt extract task {task_name}
|
|
196
|
+
|
|
197
|
+
ara config examples:
|
|
198
|
+
> show current configuration status: ara config show
|
|
199
|
+
> show only LLM configurations: ara config show --llm
|
|
200
|
+
> reset LLM configurations to defaults: ara config reset --llm-config -y
|
|
201
|
+
> preview reset without making changes: ara config reset --all --dry-run
|
|
207
202
|
""",
|
|
208
203
|
no_args_is_help=True,
|
|
209
204
|
add_completion=True,
|
|
210
|
-
rich_markup_mode="rich"
|
|
205
|
+
rich_markup_mode="rich",
|
|
211
206
|
)
|
|
212
207
|
|
|
213
208
|
@app.callback(invoke_without_command=True)
|
|
214
209
|
def main(
|
|
215
210
|
ctx: typer.Context,
|
|
216
211
|
version: Optional[bool] = typer.Option(
|
|
217
|
-
None,
|
|
212
|
+
None,
|
|
213
|
+
"--version",
|
|
214
|
+
"-v",
|
|
218
215
|
callback=version_callback,
|
|
219
216
|
is_eager=True,
|
|
220
|
-
help="Show version and exit"
|
|
217
|
+
help="Show version and exit",
|
|
221
218
|
),
|
|
222
219
|
debug: bool = typer.Option(
|
|
223
|
-
False, "--debug",
|
|
224
|
-
|
|
225
|
-
)
|
|
220
|
+
False, "--debug", help="Enable debug mode for detailed error output"
|
|
221
|
+
),
|
|
226
222
|
):
|
|
227
223
|
"""The ara cli terminal tool is a management tool for classified ara artefacts."""
|
|
228
224
|
debug_mode = is_debug_mode_enabled()
|
|
@@ -232,15 +228,26 @@ ara chat examples:
|
|
|
232
228
|
if ctx.invoked_subcommand is None:
|
|
233
229
|
ctx.get_help()
|
|
234
230
|
ctx.exit()
|
|
235
|
-
|
|
231
|
+
|
|
236
232
|
# Check for ara directory before executing any command
|
|
237
233
|
# Skip check for commands that don't require ara directory
|
|
238
234
|
commands_requiring_ara = {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
235
|
+
"create",
|
|
236
|
+
"delete",
|
|
237
|
+
"rename",
|
|
238
|
+
"list",
|
|
239
|
+
"list-tags",
|
|
240
|
+
"prompt",
|
|
241
|
+
"read",
|
|
242
|
+
"reconnect",
|
|
243
|
+
"read-status",
|
|
244
|
+
"read-user",
|
|
245
|
+
"set-status",
|
|
246
|
+
"set-user",
|
|
247
|
+
"scan",
|
|
248
|
+
"autofix",
|
|
242
249
|
}
|
|
243
|
-
|
|
250
|
+
|
|
244
251
|
if ctx.invoked_subcommand in commands_requiring_ara:
|
|
245
252
|
requires_ara_directory()
|
|
246
253
|
|
|
@@ -254,6 +261,9 @@ ara chat examples:
|
|
|
254
261
|
register_chat_cli(app)
|
|
255
262
|
register_template_cli(app)
|
|
256
263
|
register_fetch_templates_cli(app)
|
|
264
|
+
register_fetch_scripts_cli(app)
|
|
265
|
+
register_fetch_agents_cli(app)
|
|
266
|
+
register_fetch_cli(app)
|
|
257
267
|
register_read_cli(app)
|
|
258
268
|
register_reconnect_cli(app)
|
|
259
269
|
register_read_status_cli(app)
|
|
@@ -265,6 +275,8 @@ ara chat examples:
|
|
|
265
275
|
register_autofix_cli(app)
|
|
266
276
|
register_extract_cli(app)
|
|
267
277
|
register_load_cli(app)
|
|
278
|
+
register_config_cli(app)
|
|
279
|
+
register_convert_cli(app)
|
|
268
280
|
|
|
269
281
|
return app
|
|
270
282
|
|
|
@@ -281,4 +293,4 @@ def cli():
|
|
|
281
293
|
|
|
282
294
|
|
|
283
295
|
if __name__ == "__main__":
|
|
284
|
-
cli()
|
|
296
|
+
cli()
|
ara_cli/ara_command_action.py
CHANGED
|
@@ -23,24 +23,33 @@ 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),
|
|
27
|
-
|
|
26
|
+
check_validity(Classifier.is_valid_classifier(args.classifier),
|
|
27
|
+
"Invalid classifier provided. Please provide a valid classifier.")
|
|
28
|
+
check_validity(is_valid_filename(args.parameter),
|
|
29
|
+
"Invalid filename provided. Please provide a valid filename.")
|
|
28
30
|
|
|
29
31
|
def handle_parent_arguments(args):
|
|
30
|
-
parent_classifier = args.parent_classifier if hasattr(
|
|
31
|
-
|
|
32
|
+
parent_classifier = args.parent_classifier if hasattr(
|
|
33
|
+
args, "parent_classifier") else None
|
|
34
|
+
parent_name = args.parent_name if hasattr(
|
|
35
|
+
args, "parent_name") else None
|
|
32
36
|
rule = args.rule if hasattr(args, 'rule') else None
|
|
33
37
|
invalid_classifier_message = "Invalid parent classifier provided. Please provide a valid classifier"
|
|
34
38
|
invalid_name_message = "Invalid filename provided for parent. Please provide a valid filename."
|
|
35
39
|
if parent_classifier and parent_name and rule:
|
|
36
|
-
check_validity(Classifier.is_valid_classifier(
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
check_validity(Classifier.is_valid_classifier(
|
|
41
|
+
parent_classifier), invalid_classifier_message)
|
|
42
|
+
check_validity(is_valid_filename(
|
|
43
|
+
parent_name), invalid_name_message)
|
|
44
|
+
parent_artefact = ArtefactReader.read_artefact(
|
|
45
|
+
artefact_name=parent_name, classifier=parent_classifier)
|
|
39
46
|
rule = find_closest_rule(parent_artefact, rule)
|
|
40
47
|
return parent_classifier, parent_name, rule
|
|
41
48
|
if parent_classifier and parent_name:
|
|
42
|
-
check_validity(Classifier.is_valid_classifier(
|
|
43
|
-
|
|
49
|
+
check_validity(Classifier.is_valid_classifier(
|
|
50
|
+
parent_classifier), invalid_classifier_message)
|
|
51
|
+
check_validity(is_valid_filename(
|
|
52
|
+
parent_name), invalid_name_message)
|
|
44
53
|
return parent_classifier, parent_name, rule
|
|
45
54
|
return None, None, None
|
|
46
55
|
|
|
@@ -61,7 +70,8 @@ def create_action(args):
|
|
|
61
70
|
return
|
|
62
71
|
|
|
63
72
|
artefact_creator = ArtefactCreator()
|
|
64
|
-
artefact_creator.run(args.parameter, args.classifier,
|
|
73
|
+
artefact_creator.run(args.parameter, args.classifier,
|
|
74
|
+
parent_classifier, parent_name, rule)
|
|
65
75
|
|
|
66
76
|
|
|
67
77
|
@handle_errors(context="delete action", error_handler=error_handler)
|
|
@@ -78,22 +88,33 @@ def rename_action(args):
|
|
|
78
88
|
from ara_cli.classifier import Classifier
|
|
79
89
|
from ara_cli.filename_validator import is_valid_filename
|
|
80
90
|
|
|
81
|
-
check_validity(is_valid_filename(args.parameter),
|
|
82
|
-
|
|
83
|
-
check_validity(
|
|
91
|
+
check_validity(is_valid_filename(args.parameter),
|
|
92
|
+
"Invalid filename provided. Please provide a valid filename.")
|
|
93
|
+
check_validity(Classifier.is_valid_classifier(args.classifier),
|
|
94
|
+
"Invalid classifier provided. Please provide a valid classifier.")
|
|
95
|
+
check_validity(is_valid_filename(
|
|
96
|
+
args.aspect), "Invalid new filename provided. Please provide a valid filename.")
|
|
84
97
|
|
|
85
98
|
artefact_renamer = ArtefactRenamer()
|
|
86
99
|
artefact_renamer.rename(args.parameter, args.aspect, args.classifier)
|
|
87
100
|
|
|
88
101
|
|
|
102
|
+
def _execute_list_method(method, classifier, artefact_name, list_filter, flag_name):
|
|
103
|
+
"""Helper function to validate and execute list methods."""
|
|
104
|
+
if not classifier or not artefact_name:
|
|
105
|
+
raise AraError(
|
|
106
|
+
f"Both classifier and artefact_name are required for --{flag_name}"
|
|
107
|
+
)
|
|
108
|
+
method(classifier=classifier, artefact_name=artefact_name, list_filter=list_filter)
|
|
109
|
+
|
|
110
|
+
|
|
89
111
|
@handle_errors(context="rename action", error_handler=error_handler)
|
|
90
112
|
def list_action(args):
|
|
91
113
|
from ara_cli.artefact_lister import ArtefactLister
|
|
92
114
|
from ara_cli.list_filter import ListFilter
|
|
93
115
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
data_classifier, data_artefact_name = args.data_args
|
|
116
|
+
classifier = args.classifier
|
|
117
|
+
artefact_name = args.artefact_name
|
|
97
118
|
|
|
98
119
|
artefact_lister = ArtefactLister()
|
|
99
120
|
|
|
@@ -106,29 +127,27 @@ def list_action(args):
|
|
|
106
127
|
exclude_tags=args.exclude_tags
|
|
107
128
|
)
|
|
108
129
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
|
130
|
+
# Map flags to their corresponding methods
|
|
131
|
+
flag_method_map = {
|
|
132
|
+
"branch": (args.branch, artefact_lister.list_branch),
|
|
133
|
+
"children": (args.children, artefact_lister.list_children),
|
|
134
|
+
"data": (args.data, artefact_lister.list_data),
|
|
135
|
+
}
|
|
124
136
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
137
|
+
for flag_name, (flag_value, method) in flag_method_map.items():
|
|
138
|
+
if flag_value:
|
|
139
|
+
_execute_list_method(
|
|
140
|
+
method, classifier, artefact_name, list_filter, flag_name
|
|
141
|
+
)
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
# If both classifier and artefact_name are present, but no specific action flag (branch, children, data)
|
|
145
|
+
# was provided, raise an error as per requirements.
|
|
146
|
+
if classifier and artefact_name:
|
|
147
|
+
raise AraError(
|
|
148
|
+
f"To list specific info for '{classifier} {artefact_name}', "
|
|
149
|
+
"you must provide one of: --children, --branch, or --data."
|
|
130
150
|
)
|
|
131
|
-
return
|
|
132
151
|
|
|
133
152
|
artefact_lister.list_files(list_filter=list_filter)
|
|
134
153
|
|
|
@@ -171,8 +190,10 @@ def prompt_action(args):
|
|
|
171
190
|
from ara_cli.classifier import Classifier
|
|
172
191
|
from ara_cli.filename_validator import is_valid_filename
|
|
173
192
|
|
|
174
|
-
check_validity(Classifier.is_valid_classifier(args.classifier),
|
|
175
|
-
|
|
193
|
+
check_validity(Classifier.is_valid_classifier(args.classifier),
|
|
194
|
+
"Invalid classifier provided. Please provide a valid classifier.")
|
|
195
|
+
check_validity(is_valid_filename(args.parameter),
|
|
196
|
+
"Invalid filename provided. Please provide a valid filename.")
|
|
176
197
|
|
|
177
198
|
classifier = args.classifier
|
|
178
199
|
param = args.parameter
|
|
@@ -207,7 +228,8 @@ def prompt_action(args):
|
|
|
207
228
|
from ara_cli.update_config_prompt import update_artefact_config_prompt_files
|
|
208
229
|
extract_and_save_prompt_results(classifier, param, write=write)
|
|
209
230
|
print(f"automatic update after extract")
|
|
210
|
-
update_artefact_config_prompt_files(
|
|
231
|
+
update_artefact_config_prompt_files(
|
|
232
|
+
classifier, param, automatic_update=True)
|
|
211
233
|
|
|
212
234
|
def handle_chat():
|
|
213
235
|
from ara_cli.prompt_chat import initialize_prompt_chat_mode
|
|
@@ -216,11 +238,13 @@ def prompt_action(args):
|
|
|
216
238
|
output_mode = args.output_mode
|
|
217
239
|
append_strings = args.append
|
|
218
240
|
restricted = args.restricted
|
|
219
|
-
initialize_prompt_chat_mode(classifier, param, chat_name, reset=reset,
|
|
241
|
+
initialize_prompt_chat_mode(classifier, param, chat_name, reset=reset,
|
|
242
|
+
output_mode=output_mode, append_strings=append_strings, restricted=restricted)
|
|
220
243
|
|
|
221
244
|
def handle_update():
|
|
222
245
|
from ara_cli.update_config_prompt import update_artefact_config_prompt_files
|
|
223
|
-
update_artefact_config_prompt_files(
|
|
246
|
+
update_artefact_config_prompt_files(
|
|
247
|
+
classifier, param, automatic_update=True)
|
|
224
248
|
|
|
225
249
|
command_dispatcher = {
|
|
226
250
|
'init': handle_init,
|
|
@@ -255,7 +279,8 @@ def chat_action(args):
|
|
|
255
279
|
chat_file_path = join(cwd, chat_name)
|
|
256
280
|
|
|
257
281
|
with suppress_stdout(output_mode):
|
|
258
|
-
chat = Chat(chat_file_path, reset=reset) if not restricted else Chat(
|
|
282
|
+
chat = Chat(chat_file_path, reset=reset) if not restricted else Chat(
|
|
283
|
+
chat_file_path, reset=reset, enable_commands=whitelisted_commands)
|
|
259
284
|
|
|
260
285
|
if append_strings:
|
|
261
286
|
chat.append_strings(append_strings)
|
|
@@ -305,7 +330,8 @@ def load_action(args):
|
|
|
305
330
|
default_pattern = default_patterns.get(template_type)
|
|
306
331
|
|
|
307
332
|
if not template_name and not default_pattern:
|
|
308
|
-
raise AraError(
|
|
333
|
+
raise AraError(
|
|
334
|
+
f"A template name is required for template type '{template_type}'.")
|
|
309
335
|
|
|
310
336
|
loader = TemplateLoader() # No chat instance for CLI context
|
|
311
337
|
success = loader.load_template(
|
|
@@ -324,7 +350,8 @@ def template_action(args):
|
|
|
324
350
|
from ara_cli.classifier import Classifier
|
|
325
351
|
from ara_cli.template_manager import TemplatePathManager
|
|
326
352
|
|
|
327
|
-
check_validity(Classifier.is_valid_classifier(args.classifier),
|
|
353
|
+
check_validity(Classifier.is_valid_classifier(args.classifier),
|
|
354
|
+
"Invalid classifier provided. Please provide a valid classifier.")
|
|
328
355
|
|
|
329
356
|
template_manager = TemplatePathManager()
|
|
330
357
|
content = template_manager.get_template_content(args.classifier)
|
|
@@ -345,9 +372,11 @@ def fetch_templates_action(args):
|
|
|
345
372
|
|
|
346
373
|
subdirs = ["commands", "rules", "intentions", "blueprints"]
|
|
347
374
|
|
|
348
|
-
os.makedirs(join(prompt_templates_dir,
|
|
375
|
+
os.makedirs(join(prompt_templates_dir,
|
|
376
|
+
"global-prompt-modules"), exist_ok=True)
|
|
349
377
|
for subdir in subdirs:
|
|
350
|
-
target_dir = join(prompt_templates_dir,
|
|
378
|
+
target_dir = join(prompt_templates_dir,
|
|
379
|
+
"global-prompt-modules", subdir)
|
|
351
380
|
source_dir = join(global_prompt_templates_path, subdir)
|
|
352
381
|
os.makedirs(target_dir, exist_ok=True)
|
|
353
382
|
for item in os.listdir(source_dir):
|
|
@@ -356,7 +385,8 @@ def fetch_templates_action(args):
|
|
|
356
385
|
shutil.copy2(source, target)
|
|
357
386
|
|
|
358
387
|
custom_prompt_templates_subdir = config.custom_prompt_templates_subdir
|
|
359
|
-
local_prompt_modules_dir = join(
|
|
388
|
+
local_prompt_modules_dir = join(
|
|
389
|
+
prompt_templates_dir, custom_prompt_templates_subdir)
|
|
360
390
|
os.makedirs(local_prompt_modules_dir, exist_ok=True)
|
|
361
391
|
for subdir in subdirs:
|
|
362
392
|
os.makedirs(join(local_prompt_modules_dir, subdir), exist_ok=True)
|
|
@@ -459,9 +489,11 @@ def read_status_action(args):
|
|
|
459
489
|
artefact_info = file_classifier.classify_files()
|
|
460
490
|
artefact_info_dicts = artefact_info.get(classifier, [])
|
|
461
491
|
|
|
462
|
-
all_artefact_names = [artefact_info["title"]
|
|
492
|
+
all_artefact_names = [artefact_info["title"]
|
|
493
|
+
for artefact_info in artefact_info_dicts]
|
|
463
494
|
if artefact_name not in all_artefact_names:
|
|
464
|
-
suggest_close_name_matches(
|
|
495
|
+
suggest_close_name_matches(
|
|
496
|
+
artefact_name, all_artefact_names, report_as_error=True)
|
|
465
497
|
return
|
|
466
498
|
|
|
467
499
|
artefact_info = next(filter(
|
|
@@ -492,9 +524,11 @@ def read_user_action(args):
|
|
|
492
524
|
artefact_info = file_classifier.classify_files()
|
|
493
525
|
artefact_info_dicts = artefact_info.get(classifier, [])
|
|
494
526
|
|
|
495
|
-
all_artefact_names = [artefact_info["title"]
|
|
527
|
+
all_artefact_names = [artefact_info["title"]
|
|
528
|
+
for artefact_info in artefact_info_dicts]
|
|
496
529
|
if artefact_name not in all_artefact_names:
|
|
497
|
-
suggest_close_name_matches(
|
|
530
|
+
suggest_close_name_matches(
|
|
531
|
+
artefact_name, all_artefact_names, report_as_error=True)
|
|
498
532
|
return
|
|
499
533
|
|
|
500
534
|
artefact_info = next(filter(
|
|
@@ -529,12 +563,14 @@ def set_status_action(args):
|
|
|
529
563
|
if new_status.startswith('@'):
|
|
530
564
|
new_status = new_status.lstrip('@')
|
|
531
565
|
|
|
532
|
-
check_validity(new_status in status_tags,
|
|
566
|
+
check_validity(new_status in status_tags,
|
|
567
|
+
"Invalid status provided. Please provide a valid status.")
|
|
533
568
|
|
|
534
569
|
file_classifier = FileClassifier(os)
|
|
535
570
|
classified_artefacts_info = file_classifier.classify_files()
|
|
536
571
|
classified_artefact_dict = classified_artefacts_info.get(classifier, [])
|
|
537
|
-
all_artefact_names = [artefact_info["title"]
|
|
572
|
+
all_artefact_names = [artefact_info["title"]
|
|
573
|
+
for artefact_info in classified_artefact_dict]
|
|
538
574
|
|
|
539
575
|
if artefact_name not in all_artefact_names:
|
|
540
576
|
suggest_close_name_matches(artefact_name, all_artefact_names)
|
|
@@ -554,7 +590,8 @@ def set_status_action(args):
|
|
|
554
590
|
with open(f"{artefact_info['file_path']}", 'w', encoding='utf-8') as file:
|
|
555
591
|
file.write(serialized_content)
|
|
556
592
|
|
|
557
|
-
print(
|
|
593
|
+
print(
|
|
594
|
+
f"Status of task '{artefact_name}' has been updated to '{new_status}'.")
|
|
558
595
|
|
|
559
596
|
|
|
560
597
|
@handle_errors(context="set-user action", error_handler=error_handler)
|
|
@@ -572,7 +609,8 @@ def set_user_action(args):
|
|
|
572
609
|
file_classifier = FileClassifier(os)
|
|
573
610
|
classified_artefacts_info = file_classifier.classify_files()
|
|
574
611
|
classified_artefact_dict = classified_artefacts_info.get(classifier, [])
|
|
575
|
-
all_artefact_names = [artefact_info["title"]
|
|
612
|
+
all_artefact_names = [artefact_info["title"]
|
|
613
|
+
for artefact_info in classified_artefact_dict]
|
|
576
614
|
|
|
577
615
|
if artefact_name not in all_artefact_names:
|
|
578
616
|
suggest_close_name_matches(artefact_name, all_artefact_names)
|
|
@@ -673,4 +711,4 @@ def extract_action(args):
|
|
|
673
711
|
write=write,
|
|
674
712
|
output=lambda msg: print(msg, file=sys.stdout)
|
|
675
713
|
)
|
|
676
|
-
command.execute()
|
|
714
|
+
command.execute()
|