ara-cli 0.1.9.96__py3-none-any.whl → 0.1.10.1__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.
Potentially problematic release.
This version of ara-cli might be problematic. Click here for more details.
- ara_cli/__init__.py +1 -1
- ara_cli/__main__.py +141 -103
- ara_cli/ara_command_action.py +65 -7
- ara_cli/ara_config.py +118 -94
- ara_cli/ara_subcommands/__init__.py +0 -0
- ara_cli/ara_subcommands/autofix.py +26 -0
- ara_cli/ara_subcommands/chat.py +27 -0
- ara_cli/ara_subcommands/classifier_directory.py +16 -0
- ara_cli/ara_subcommands/common.py +100 -0
- ara_cli/ara_subcommands/create.py +75 -0
- ara_cli/ara_subcommands/delete.py +22 -0
- ara_cli/ara_subcommands/extract.py +22 -0
- ara_cli/ara_subcommands/fetch_templates.py +14 -0
- ara_cli/ara_subcommands/list.py +65 -0
- ara_cli/ara_subcommands/list_tags.py +25 -0
- ara_cli/ara_subcommands/load.py +48 -0
- ara_cli/ara_subcommands/prompt.py +136 -0
- ara_cli/ara_subcommands/read.py +47 -0
- ara_cli/ara_subcommands/read_status.py +20 -0
- ara_cli/ara_subcommands/read_user.py +20 -0
- ara_cli/ara_subcommands/reconnect.py +27 -0
- ara_cli/ara_subcommands/rename.py +22 -0
- ara_cli/ara_subcommands/scan.py +14 -0
- ara_cli/ara_subcommands/set_status.py +22 -0
- ara_cli/ara_subcommands/set_user.py +22 -0
- ara_cli/ara_subcommands/template.py +16 -0
- ara_cli/artefact_models/artefact_model.py +88 -19
- ara_cli/artefact_models/artefact_templates.py +18 -9
- ara_cli/artefact_models/userstory_artefact_model.py +2 -2
- ara_cli/artefact_scan.py +2 -2
- ara_cli/chat.py +204 -142
- ara_cli/commands/read_command.py +17 -4
- ara_cli/completers.py +144 -0
- ara_cli/prompt_handler.py +268 -127
- ara_cli/tag_extractor.py +33 -16
- ara_cli/template_loader.py +245 -0
- ara_cli/version.py +1 -1
- {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/METADATA +3 -1
- {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/RECORD +47 -23
- tests/test_artefact_scan.py +1 -1
- tests/test_chat.py +1840 -574
- tests/test_prompt_handler.py +40 -4
- tests/test_tag_extractor.py +19 -13
- tests/test_template_loader.py +192 -0
- ara_cli/ara_command_parser.py +0 -565
- {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/WHEEL +0 -0
- {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/entry_points.txt +0 -0
- {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/top_level.txt +0 -0
ara_cli/tag_extractor.py
CHANGED
|
@@ -11,13 +11,13 @@ class TagExtractor:
|
|
|
11
11
|
def __init__(self, file_system=None):
|
|
12
12
|
self.file_system = file_system or os
|
|
13
13
|
|
|
14
|
-
def filter_column(self,
|
|
14
|
+
def filter_column(self, tag_groups, filtered_artefacts):
|
|
15
15
|
status_tags = {"to-do", "in-progress", "review", "done", "closed"}
|
|
16
16
|
|
|
17
17
|
artefacts_to_process = self._get_artefacts_without_status_tags(
|
|
18
18
|
filtered_artefacts, status_tags
|
|
19
19
|
)
|
|
20
|
-
self._add_non_status_tags_to_set(
|
|
20
|
+
self._add_non_status_tags_to_set(tag_groups, artefacts_to_process, status_tags)
|
|
21
21
|
|
|
22
22
|
def _get_artefacts_without_status_tags(self, filtered_artefacts, status_tags):
|
|
23
23
|
artefacts_to_process = []
|
|
@@ -32,7 +32,7 @@ class TagExtractor:
|
|
|
32
32
|
tags = artefact.tags + [artefact.status] if artefact.status else artefact.tags
|
|
33
33
|
return set(tag for tag in tags if tag is not None)
|
|
34
34
|
|
|
35
|
-
def _add_non_status_tags_to_set(self,
|
|
35
|
+
def _add_non_status_tags_to_set(self, tag_groups, artefacts, status_tags):
|
|
36
36
|
for artefact in artefacts:
|
|
37
37
|
tags = [
|
|
38
38
|
tag for tag in (artefact.tags + [artefact.status]) if tag is not None
|
|
@@ -40,23 +40,41 @@ class TagExtractor:
|
|
|
40
40
|
for tag in tags:
|
|
41
41
|
if self._is_skipped_tag(tag, status_tags):
|
|
42
42
|
continue
|
|
43
|
-
|
|
43
|
+
key = tag.lower()
|
|
44
|
+
if key not in tag_groups:
|
|
45
|
+
tag_groups[key] = set()
|
|
46
|
+
tag_groups[key].add(tag)
|
|
44
47
|
|
|
45
48
|
def _is_skipped_tag(self, tag, status_tags):
|
|
46
49
|
return (
|
|
47
50
|
tag in status_tags or tag.startswith("priority_") or tag.startswith("user_")
|
|
48
51
|
)
|
|
49
52
|
|
|
50
|
-
def add_to_tags_set(self,
|
|
53
|
+
def add_to_tags_set(self, tag_groups, filtered_artefacts):
|
|
51
54
|
for artefact_list in filtered_artefacts.values():
|
|
52
55
|
for artefact in artefact_list:
|
|
53
56
|
user_tags = [f"user_{tag}" for tag in artefact.users]
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
|
|
58
|
+
# Build list of all tags, filtering out None values
|
|
59
|
+
all_tags = []
|
|
60
|
+
all_tags.extend(artefact.tags)
|
|
61
|
+
|
|
62
|
+
if artefact.status:
|
|
63
|
+
all_tags.append(artefact.status)
|
|
64
|
+
|
|
65
|
+
all_tags.extend(user_tags)
|
|
66
|
+
|
|
67
|
+
# Safely handle author attribute
|
|
68
|
+
if hasattr(artefact, 'author') and artefact.author:
|
|
69
|
+
all_tags.append(artefact.author)
|
|
70
|
+
|
|
71
|
+
# Filter out None values and add to tag groups
|
|
72
|
+
for tag in all_tags:
|
|
73
|
+
if tag is not None:
|
|
74
|
+
key = tag.lower()
|
|
75
|
+
if key not in tag_groups:
|
|
76
|
+
tag_groups[key] = set()
|
|
77
|
+
tag_groups[key].add(tag)
|
|
60
78
|
|
|
61
79
|
def extract_tags(
|
|
62
80
|
self,
|
|
@@ -81,12 +99,11 @@ class TagExtractor:
|
|
|
81
99
|
tag_retrieval=artefact_tags_retrieval,
|
|
82
100
|
)
|
|
83
101
|
|
|
84
|
-
|
|
102
|
+
tag_groups = {}
|
|
85
103
|
|
|
86
104
|
if filtered_extra_column:
|
|
87
|
-
self.filter_column(
|
|
105
|
+
self.filter_column(tag_groups, filtered_artefacts)
|
|
88
106
|
else:
|
|
89
|
-
self.add_to_tags_set(
|
|
107
|
+
self.add_to_tags_set(tag_groups, filtered_artefacts)
|
|
90
108
|
|
|
91
|
-
|
|
92
|
-
return sorted_tags
|
|
109
|
+
return tag_groups
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
|
|
2
|
+
import os
|
|
3
|
+
import glob
|
|
4
|
+
from ara_cli.template_manager import TemplatePathManager
|
|
5
|
+
from ara_cli.ara_config import ConfigManager
|
|
6
|
+
from ara_cli.directory_navigator import DirectoryNavigator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TemplateLoader:
|
|
10
|
+
"""Handles template loading logic shared between CLI and chat commands"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, chat_instance=None):
|
|
13
|
+
self.chat_instance = chat_instance
|
|
14
|
+
|
|
15
|
+
def load_template(self, template_name: str, template_type: str, chat_file_path: str, default_pattern: str | None = None) -> bool:
|
|
16
|
+
if not template_name:
|
|
17
|
+
if default_pattern:
|
|
18
|
+
return self.load_template_from_prompt_data(template_type, default_pattern, chat_file_path)
|
|
19
|
+
else:
|
|
20
|
+
print(f"A template name is required for template type '{template_type}'.")
|
|
21
|
+
return False
|
|
22
|
+
return self.load_template_from_global_or_local(template_name, template_type, chat_file_path)
|
|
23
|
+
|
|
24
|
+
def get_plural_template_type(self, template_type: str) -> str:
|
|
25
|
+
"""Determines the plural form of a template type."""
|
|
26
|
+
plurals = {"commands": "commands", "rules": "rules"}
|
|
27
|
+
return plurals.get(template_type, f"{template_type}s")
|
|
28
|
+
|
|
29
|
+
def load_template_from_global_or_local(self, template_name: str, template_type: str, chat_file_path: str) -> bool:
|
|
30
|
+
"""Load template from global or local directories"""
|
|
31
|
+
plural = self.get_plural_template_type(template_type)
|
|
32
|
+
|
|
33
|
+
if template_name.startswith("global/"):
|
|
34
|
+
return self._load_global_template(template_name, template_type, plural, chat_file_path)
|
|
35
|
+
else:
|
|
36
|
+
return self._load_local_template(template_name, template_type, plural, chat_file_path)
|
|
37
|
+
|
|
38
|
+
def _choose_file_for_cli(self, files: list[str], pattern: str) -> str | None:
|
|
39
|
+
"""CLI-compatible file selection method"""
|
|
40
|
+
if len(files) <= 1:
|
|
41
|
+
return files[0] if files else None
|
|
42
|
+
|
|
43
|
+
if pattern in ["*", "global/*"] or "*" in pattern:
|
|
44
|
+
files.sort()
|
|
45
|
+
print("Multiple files found:")
|
|
46
|
+
for i, file in enumerate(files):
|
|
47
|
+
print(f"{i + 1}: {os.path.basename(file)}")
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
choice = input("Please choose a file to load (enter number): ")
|
|
51
|
+
choice_index = int(choice) - 1
|
|
52
|
+
if 0 <= choice_index < len(files):
|
|
53
|
+
return files[choice_index]
|
|
54
|
+
else:
|
|
55
|
+
print("Invalid choice. Aborting load.")
|
|
56
|
+
return None
|
|
57
|
+
except (ValueError, KeyboardInterrupt):
|
|
58
|
+
print("Invalid input. Aborting load.")
|
|
59
|
+
return None
|
|
60
|
+
else:
|
|
61
|
+
return files[0]
|
|
62
|
+
|
|
63
|
+
def _load_global_template(self, template_name: str, template_type: str, plural: str, chat_file_path: str) -> bool:
|
|
64
|
+
"""Load template from global directory"""
|
|
65
|
+
directory = f"{TemplatePathManager.get_template_base_path()}/prompt-modules/{plural}/"
|
|
66
|
+
template_file = template_name.removeprefix("global/")
|
|
67
|
+
file_pattern = os.path.join(directory, template_file)
|
|
68
|
+
matching_files = glob.glob(file_pattern)
|
|
69
|
+
|
|
70
|
+
if not matching_files:
|
|
71
|
+
print(f"No {template_type} template '{template_file}' found in global templates.")
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
# Choose file based on context
|
|
75
|
+
if self.chat_instance:
|
|
76
|
+
file_path = self.chat_instance.choose_file_to_load(matching_files, template_file)
|
|
77
|
+
else:
|
|
78
|
+
file_path = self._choose_file_for_cli(matching_files, template_file)
|
|
79
|
+
|
|
80
|
+
if file_path is None:
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
return self._load_file_to_chat(file_path, template_type, chat_file_path)
|
|
84
|
+
|
|
85
|
+
def _load_local_template(self, template_name: str, template_type: str, plural: str, chat_file_path: str) -> bool:
|
|
86
|
+
"""Load template from local custom directory"""
|
|
87
|
+
ara_config = ConfigManager.get_config()
|
|
88
|
+
navigator = DirectoryNavigator()
|
|
89
|
+
|
|
90
|
+
original_directory = os.getcwd()
|
|
91
|
+
navigator.navigate_to_target()
|
|
92
|
+
local_templates_path = ara_config.local_prompt_templates_dir
|
|
93
|
+
os.chdir("..")
|
|
94
|
+
local_templates_path = os.path.join(os.getcwd(), local_templates_path)
|
|
95
|
+
os.chdir(original_directory)
|
|
96
|
+
|
|
97
|
+
custom_prompt_templates_subdir = ara_config.custom_prompt_templates_subdir
|
|
98
|
+
template_directory = f"{local_templates_path}/{custom_prompt_templates_subdir}/{plural}"
|
|
99
|
+
file_pattern = os.path.join(template_directory, template_name)
|
|
100
|
+
matching_files = glob.glob(file_pattern)
|
|
101
|
+
|
|
102
|
+
if not matching_files:
|
|
103
|
+
print(f"No {template_type} template '{template_name}' found in local templates.")
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
# Choose file based on context
|
|
107
|
+
if self.chat_instance:
|
|
108
|
+
file_path = self.chat_instance.choose_file_to_load(matching_files, template_name)
|
|
109
|
+
else:
|
|
110
|
+
file_path = self._choose_file_for_cli(matching_files, template_name)
|
|
111
|
+
|
|
112
|
+
if file_path is None:
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
return self._load_file_to_chat(file_path, template_type, chat_file_path)
|
|
116
|
+
|
|
117
|
+
def load_template_from_prompt_data(self, template_type: str, default_pattern: str, chat_file_path: str) -> bool:
|
|
118
|
+
"""Load template from prompt.data directory with selection"""
|
|
119
|
+
directory_path = os.path.join(os.path.dirname(chat_file_path), "prompt.data")
|
|
120
|
+
file_pattern = os.path.join(directory_path, default_pattern)
|
|
121
|
+
matching_files = glob.glob(file_pattern)
|
|
122
|
+
|
|
123
|
+
if not matching_files:
|
|
124
|
+
print(f"No {template_type} file found in prompt.data directory.")
|
|
125
|
+
return False
|
|
126
|
+
|
|
127
|
+
# Choose file based on context
|
|
128
|
+
if self.chat_instance:
|
|
129
|
+
file_path = self.chat_instance.choose_file_to_load(matching_files, default_pattern)
|
|
130
|
+
else:
|
|
131
|
+
file_path = self._choose_file_for_cli(matching_files, "*")
|
|
132
|
+
|
|
133
|
+
if file_path is None:
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
return self._load_file_to_chat(file_path, template_type, chat_file_path)
|
|
137
|
+
|
|
138
|
+
def _load_file_to_chat(self, file_path: str, template_type: str, chat_file_path: str) -> bool:
|
|
139
|
+
"""Load a file into the chat file"""
|
|
140
|
+
if self.chat_instance:
|
|
141
|
+
# Use chat instance methods
|
|
142
|
+
self.chat_instance.add_prompt_tag_if_needed(chat_file_path)
|
|
143
|
+
if self.chat_instance.load_file(file_path):
|
|
144
|
+
print(f"Loaded {template_type} from {os.path.basename(file_path)} into {os.path.basename(chat_file_path)}")
|
|
145
|
+
return True
|
|
146
|
+
else:
|
|
147
|
+
# Direct file loading for CLI usage
|
|
148
|
+
try:
|
|
149
|
+
with open(file_path, 'r', encoding='utf-8') as template_file:
|
|
150
|
+
template_content = template_file.read()
|
|
151
|
+
|
|
152
|
+
# Add prompt tag if needed
|
|
153
|
+
self._add_prompt_tag_if_needed(chat_file_path)
|
|
154
|
+
|
|
155
|
+
# Append template content with newlines for separation
|
|
156
|
+
with open(chat_file_path, 'a', encoding='utf-8') as chat_file:
|
|
157
|
+
chat_file.write(f"\n{template_content}\n")
|
|
158
|
+
|
|
159
|
+
print(f"Loaded {template_type} from {os.path.basename(file_path)} into {os.path.basename(chat_file_path)}")
|
|
160
|
+
return True
|
|
161
|
+
except Exception as e:
|
|
162
|
+
print(f"Error loading {template_type} from {file_path}: {e}")
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
return False
|
|
166
|
+
|
|
167
|
+
def _add_prompt_tag_if_needed(self, chat_file_path: str):
|
|
168
|
+
"""Add prompt tag if needed for CLI usage"""
|
|
169
|
+
from ara_cli.chat import Chat
|
|
170
|
+
|
|
171
|
+
with open(chat_file_path, 'r', encoding='utf-8') as file:
|
|
172
|
+
lines = file.readlines()
|
|
173
|
+
|
|
174
|
+
prompt_tag = f"# {Chat.ROLE_PROMPT}:"
|
|
175
|
+
if Chat.get_last_role_marker(lines) == prompt_tag:
|
|
176
|
+
return
|
|
177
|
+
|
|
178
|
+
append = prompt_tag
|
|
179
|
+
if lines:
|
|
180
|
+
last_line = lines[-1].strip()
|
|
181
|
+
if last_line != "" and last_line != '\n':
|
|
182
|
+
append = f"\n{append}"
|
|
183
|
+
|
|
184
|
+
with open(chat_file_path, 'a', encoding='utf-8') as file:
|
|
185
|
+
file.write(append)
|
|
186
|
+
|
|
187
|
+
def _find_project_root(self, start_path: str) -> str | None:
|
|
188
|
+
"""
|
|
189
|
+
Finds the project root by searching for an 'ara' directory,
|
|
190
|
+
starting from the given path and moving upwards.
|
|
191
|
+
"""
|
|
192
|
+
current_dir = start_path
|
|
193
|
+
while True:
|
|
194
|
+
if os.path.isdir(os.path.join(current_dir, 'ara')):
|
|
195
|
+
return current_dir
|
|
196
|
+
parent_dir = os.path.dirname(current_dir)
|
|
197
|
+
if parent_dir == current_dir: # Reached the filesystem root
|
|
198
|
+
return None
|
|
199
|
+
current_dir = parent_dir
|
|
200
|
+
|
|
201
|
+
def _gather_templates_from_path(self, search_path: str, templates_set: set, prefix: str = ""):
|
|
202
|
+
"""
|
|
203
|
+
Scans a given path for items and adds them to the provided set,
|
|
204
|
+
optionally prepending a prefix.
|
|
205
|
+
"""
|
|
206
|
+
if not os.path.isdir(search_path):
|
|
207
|
+
return
|
|
208
|
+
for path in glob.glob(os.path.join(search_path, '*')):
|
|
209
|
+
templates_set.add(f"{prefix}{os.path.basename(path)}")
|
|
210
|
+
|
|
211
|
+
def get_available_templates(self, template_type: str, context_path: str) -> list[str]:
|
|
212
|
+
"""
|
|
213
|
+
Scans for available global and project-local custom templates.
|
|
214
|
+
This method safely searches for template files without changing the
|
|
215
|
+
current directory, making it safe for use in autocompleters.
|
|
216
|
+
Args:
|
|
217
|
+
template_type: The type of template to search for (e.g., 'rules').
|
|
218
|
+
context_path: The directory path to start the search for project root from.
|
|
219
|
+
Returns:
|
|
220
|
+
A sorted list of unique template names. Global templates are
|
|
221
|
+
prefixed with 'global/'.
|
|
222
|
+
"""
|
|
223
|
+
plural_type = self.get_plural_template_type(template_type)
|
|
224
|
+
templates = set()
|
|
225
|
+
|
|
226
|
+
# 1. Find Global Templates
|
|
227
|
+
try:
|
|
228
|
+
global_base_path = TemplatePathManager.get_template_base_path()
|
|
229
|
+
global_template_dir = os.path.join(global_base_path, "prompt-modules", plural_type)
|
|
230
|
+
self._gather_templates_from_path(global_template_dir, templates, prefix="global/")
|
|
231
|
+
except Exception:
|
|
232
|
+
pass # Silently ignore if global templates are not found
|
|
233
|
+
|
|
234
|
+
# 2. Find Local Custom Templates
|
|
235
|
+
try:
|
|
236
|
+
project_root = self._find_project_root(context_path)
|
|
237
|
+
if project_root:
|
|
238
|
+
config = ConfigManager.get_config()
|
|
239
|
+
local_templates_base = os.path.join(project_root, config.local_prompt_templates_dir)
|
|
240
|
+
custom_dir = os.path.join(local_templates_base, config.custom_prompt_templates_subdir, plural_type)
|
|
241
|
+
self._gather_templates_from_path(custom_dir, templates)
|
|
242
|
+
except Exception:
|
|
243
|
+
pass # Silently ignore if local templates cannot be resolved
|
|
244
|
+
|
|
245
|
+
return sorted(list(templates))
|
ara_cli/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# version.py
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.10.1" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ara_cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10.1
|
|
4
4
|
Summary: Powerful, open source command-line tool for managing, structuring and automating software development artifacts in line with Business-Driven Development (BDD) and AI-assisted processes
|
|
5
5
|
Description-Content-Type: text/markdown
|
|
6
|
+
Requires-Dist: langfuse
|
|
6
7
|
Requires-Dist: litellm
|
|
7
8
|
Requires-Dist: llama-index
|
|
8
9
|
Requires-Dist: llama-index-llms-openai
|
|
@@ -18,6 +19,7 @@ Requires-Dist: pydantic
|
|
|
18
19
|
Requires-Dist: pydantic_ai
|
|
19
20
|
Requires-Dist: python-docx
|
|
20
21
|
Requires-Dist: pymupdf4llm
|
|
22
|
+
Requires-Dist: typer
|
|
21
23
|
Dynamic: description
|
|
22
24
|
Dynamic: description-content-type
|
|
23
25
|
Dynamic: requires-dist
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
ara_cli/__init__.py,sha256=
|
|
2
|
-
ara_cli/__main__.py,sha256=
|
|
3
|
-
ara_cli/ara_command_action.py,sha256=
|
|
4
|
-
ara_cli/
|
|
5
|
-
ara_cli/ara_config.py,sha256=VJeage_v-446OtSXIfpazUbetpH7kGNv8Un1lKYx5ZE,9321
|
|
1
|
+
ara_cli/__init__.py,sha256=DuzXKimZ6JtUEnp48qCQcnojDflBtYjT6Na_twO5EzM,505
|
|
2
|
+
ara_cli/__main__.py,sha256=GA9iL-Hi8M4LMBALNdycCP5Uo-jLp5IHRPHrgsgwWvo,8188
|
|
3
|
+
ara_cli/ara_command_action.py,sha256=yWtZXxwGp-n5kl-I6bMvwESfyRVGHHBYHVapu-8knl4,24618
|
|
4
|
+
ara_cli/ara_config.py,sha256=vZsY2zYJdlSExRE84L5LqRH3DjveeuMSmG5fC8HDIVc,9794
|
|
6
5
|
ara_cli/artefact_autofix.py,sha256=9j_bh0HGnN6HVT9OGKVp85VgDklpx3XpSc9MxBCldU4,25050
|
|
7
6
|
ara_cli/artefact_creator.py,sha256=fRrDaGZvOqJqDb_DLXqMTed2XfIvQMIHjLgOuHOi3Qg,5973
|
|
8
7
|
ara_cli/artefact_deleter.py,sha256=T1vS2s3k_BW86Sd8FExx8nC3BIL05xE9KZLkeZsZrKM,1891
|
|
@@ -11,12 +10,13 @@ ara_cli/artefact_link_updater.py,sha256=nKdxTpDKqWTOAMD8viKmUaklSFGWzJZ8S8E8xW_A
|
|
|
11
10
|
ara_cli/artefact_lister.py,sha256=M-ggazAgZ-OLeW9NB48r_sd6zPx0p4hEpeS63qHwI1A,4176
|
|
12
11
|
ara_cli/artefact_reader.py,sha256=-6E1VhIlh2oJE1Rn8ARcHRc_E9N4uk8cEViKMoywm6E,7753
|
|
13
12
|
ara_cli/artefact_renamer.py,sha256=8S4QWD19_FGKsKlWojnu_RUOxx0u9rmLugydM4s4VDc,4219
|
|
14
|
-
ara_cli/artefact_scan.py,sha256=
|
|
15
|
-
ara_cli/chat.py,sha256=
|
|
13
|
+
ara_cli/artefact_scan.py,sha256=qY2Gp4zVcqMXhtuP7rICW0UBG4pcj3W2ABofnL9SIG8,4806
|
|
14
|
+
ara_cli/chat.py,sha256=vpwVnknd_t8qihjxutw37efflPuXIce8ctMvcbLCa7c,40812
|
|
16
15
|
ara_cli/classifier.py,sha256=zWskj7rBYdqYBGjksBm46iTgVU5IIf2PZsJr4qeiwVU,1878
|
|
17
16
|
ara_cli/codefusionretriever.py,sha256=fCHgXdIBRzkVAnapX-KI2NQ44XbrrF4tEQmn5J6clUI,1980
|
|
18
17
|
ara_cli/codehierachieretriever.py,sha256=Xd3EgEWWhkSf1TmTWtf8X5_YvyE_4B66nRrqarwSiTU,1182
|
|
19
18
|
ara_cli/commandline_completer.py,sha256=b00Dqb5n7SecpxYIDLxAfYhp8X6e3c8a5qYz6ko0i3E,1192
|
|
19
|
+
ara_cli/completers.py,sha256=V4bcmUnuFkdgMpJ3bLAL7cnxinxZb8wwB17WnRHIrHM,5404
|
|
20
20
|
ara_cli/directory_navigator.py,sha256=6QbSAjJrJ5a6Lutol9J4HFgVDMiAQ672ny9TATrh04U,3318
|
|
21
21
|
ara_cli/error_handler.py,sha256=nNaJSq82f3xiz_QFRKPg5kX_-oI-UoFdRJ2OTj1AR18,4019
|
|
22
22
|
ara_cli/file_classifier.py,sha256=nUcNrhflUydCyCRbXHjEEXYwwwfUm65lYnNEvc86fpM,4026
|
|
@@ -27,19 +27,42 @@ ara_cli/list_filter.py,sha256=qKGwwQsrWe7L5FbdxEbBYD1bbbi8c-RMypjXqXvLbgs,5291
|
|
|
27
27
|
ara_cli/output_suppressor.py,sha256=nwiHaQLwabOjMoJOeUESBnZszGMxrQZfJ3N2OvahX7Y,389
|
|
28
28
|
ara_cli/prompt_chat.py,sha256=kd_OINDQFit6jN04bb7mzgY259JBbRaTaNp9F-webkc,1346
|
|
29
29
|
ara_cli/prompt_extractor.py,sha256=WloRgfcEdIVq37BpdWAd2X3EMu0bcNN_Wuws1T2YiUg,8418
|
|
30
|
-
ara_cli/prompt_handler.py,sha256=
|
|
30
|
+
ara_cli/prompt_handler.py,sha256=N0zH5k9T6udKAbMolxEAaAwiFo03h5aF-IY3BmMLEos,27924
|
|
31
31
|
ara_cli/prompt_rag.py,sha256=ydlhe4CUqz0jdzlY7jBbpKaf_5fjMrAZKnriKea3ZAg,7485
|
|
32
32
|
ara_cli/run_file_lister.py,sha256=XbrrDTJXp1LFGx9Lv91SNsEHZPP-PyEMBF_P4btjbDA,2360
|
|
33
|
-
ara_cli/tag_extractor.py,sha256=
|
|
33
|
+
ara_cli/tag_extractor.py,sha256=9yX8Ss4jP_NI-NPxxJJKoVPD-1iEweXBThUh01IU8c8,4048
|
|
34
|
+
ara_cli/template_loader.py,sha256=uEpYOchT5d-OO5r-W0-h605Xilvuv56i1VKSy4_9NaE,10734
|
|
34
35
|
ara_cli/template_manager.py,sha256=l2c785YHB7m0e2TjE0CX-nwXrS4v3EiT9qrS5KuatAc,7105
|
|
35
36
|
ara_cli/update_config_prompt.py,sha256=moqj2Kha7S7fEGzTReU0v2y8UjXC8QfnoiieOQr35C4,5157
|
|
36
|
-
ara_cli/version.py,sha256
|
|
37
|
+
ara_cli/version.py,sha256=jCeFoAxaTryn9z3M-kDldZwmzGJM9NzWxhhEBjelIFA,146
|
|
38
|
+
ara_cli/ara_subcommands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
ara_cli/ara_subcommands/autofix.py,sha256=h7-6hV97Q6PisUJ_U1Qs4sHYwkHsDpeYH63y_LQsfSc,1095
|
|
40
|
+
ara_cli/ara_subcommands/chat.py,sha256=9zorWKbM0ulu9xFhW2tzV5vl8hCLOCjcp2E9hYgZJ90,1239
|
|
41
|
+
ara_cli/ara_subcommands/classifier_directory.py,sha256=7GH3w4DtvFCM1Sr6Qqk_kjp0EC8jNJDieJJMshYJ_6k,620
|
|
42
|
+
ara_cli/ara_subcommands/common.py,sha256=6bAfPbFHx3CzDSQMm4vL7keFgVnOpqiupgDDWj7QdUQ,2898
|
|
43
|
+
ara_cli/ara_subcommands/create.py,sha256=2tIpzKgzytTIdVV26p6cvrcBo8WLm_3qK7GJyn47Jaw,2527
|
|
44
|
+
ara_cli/ara_subcommands/delete.py,sha256=DxWRQ5Z8h5ZpMhyjLHNuLxONgxIQ97hVkQ8VkX15FDk,827
|
|
45
|
+
ara_cli/ara_subcommands/extract.py,sha256=11atXek579W2RP6PYHlGuyVjWBTuyh1viondCjuce_k,765
|
|
46
|
+
ara_cli/ara_subcommands/fetch_templates.py,sha256=f1bXOTlM67hyf3oGPZEQQjSwUsTte7Cd9-yqq76Ud08,432
|
|
47
|
+
ara_cli/ara_subcommands/list.py,sha256=HtX3kKQ9nrfCcJPxJng0ZnoOqLQ11-aui2zxVei8PlI,3562
|
|
48
|
+
ara_cli/ara_subcommands/list_tags.py,sha256=drEzJgJa4OqqYfIuvT7XkjG4o7VB-ikHE0ArIdljoTI,1113
|
|
49
|
+
ara_cli/ara_subcommands/load.py,sha256=czaflU5Xv-TBlpgalvm6yn5oBBAnNfxSeoIFuLPfi-U,1825
|
|
50
|
+
ara_cli/ara_subcommands/prompt.py,sha256=A8L0lJNBm5zkwJJrzz1kpdycwpm1y8hzd2iVleylpck,4630
|
|
51
|
+
ara_cli/ara_subcommands/read.py,sha256=zTPNMvEPf1WvhtUiauXu5HFiXHRIBJVCkHu44L_scSk,2396
|
|
52
|
+
ara_cli/ara_subcommands/read_status.py,sha256=ZqdxuYXC-idJ2JtMIcZzT4XYI55PnqA6sYv2FcMuchw,695
|
|
53
|
+
ara_cli/ara_subcommands/read_user.py,sha256=NuhaC7dBbi8PUHnGGpqbBVSbQ__nT_L52c7tdKkxjlA,681
|
|
54
|
+
ara_cli/ara_subcommands/reconnect.py,sha256=5Q90rbSnYf7YO6n_9esWsYv7o8GQ-Fnzgy4d8S-X-DQ,1088
|
|
55
|
+
ara_cli/ara_subcommands/rename.py,sha256=IggQdvXjTbZ5CkqzebydVVTcaxO4SDOyORqXDL5jnY8,784
|
|
56
|
+
ara_cli/ara_subcommands/scan.py,sha256=XXwIzq4T9sDMXV0ZcMTSakQ7SyosuCfKjMiiTz7533A,363
|
|
57
|
+
ara_cli/ara_subcommands/set_status.py,sha256=6zzuqLR9k-V63e5UQBpsooftbYHuENEP2s3AdI2jyG0,786
|
|
58
|
+
ara_cli/ara_subcommands/set_user.py,sha256=ADgZIj9xIWK9QKY95lIW_GJGYZysALV--y8j6IuvGxs,755
|
|
59
|
+
ara_cli/ara_subcommands/template.py,sha256=gp_BzrNHcVylU5xav1vmPe3-0vQR7UHm44G7w2i370Q,552
|
|
37
60
|
ara_cli/artefact_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
61
|
ara_cli/artefact_models/artefact_data_retrieval.py,sha256=CooXOJBYWSyiViN2xkC8baS8OUaslry3YGVVUeDxRAU,527
|
|
39
62
|
ara_cli/artefact_models/artefact_load.py,sha256=IXzWxP-Q_j_oDGMno0m-OuXCQ7Vd5c_NctshGr4ROBw,621
|
|
40
63
|
ara_cli/artefact_models/artefact_mapping.py,sha256=8aD0spBjkJ8toMAmFawc6UTUxB6-tEEViZXv2I-r88Q,1874
|
|
41
|
-
ara_cli/artefact_models/artefact_model.py,sha256=
|
|
42
|
-
ara_cli/artefact_models/artefact_templates.py,sha256=
|
|
64
|
+
ara_cli/artefact_models/artefact_model.py,sha256=nEXbHHrYFsB4mdjKzye-RAkmFkHDyhlOzXU2ba1E4SU,18471
|
|
65
|
+
ara_cli/artefact_models/artefact_templates.py,sha256=8N1gJlS1KLd79y2nasEgU8xeK-WaP6IenBK5Ojcmn9Y,10028
|
|
43
66
|
ara_cli/artefact_models/businessgoal_artefact_model.py,sha256=GYT5S2xEnQHwv-k-lEeX5NMSqA-UEfV3PhNjgPDUJpw,4698
|
|
44
67
|
ara_cli/artefact_models/capability_artefact_model.py,sha256=SZqHx4O2mj4urn77Stnj4_Jxtlq3-LgBBU9SMkByppI,3079
|
|
45
68
|
ara_cli/artefact_models/epic_artefact_model.py,sha256=h9pC00ZxCL-t_NMjwTCeOnIJZPa9hhB-R05wr110LXs,5619
|
|
@@ -49,14 +72,14 @@ ara_cli/artefact_models/issue_artefact_model.py,sha256=v6CpKnkqiUh6Wch2kkEmyyW49
|
|
|
49
72
|
ara_cli/artefact_models/keyfeature_artefact_model.py,sha256=J9oXLsCAo22AW31D5Z104y02ss0S0O4tPCcd09zYCD0,4066
|
|
50
73
|
ara_cli/artefact_models/serialize_helper.py,sha256=Wks30wy-UrwJURetydKykLgJkdGRgXFHkDT24vHe5tU,595
|
|
51
74
|
ara_cli/artefact_models/task_artefact_model.py,sha256=1BSMbz9D-RXvdpdd0RlAr9hUx84Rcuysk2YfQC8Qy14,6046
|
|
52
|
-
ara_cli/artefact_models/userstory_artefact_model.py,sha256=
|
|
75
|
+
ara_cli/artefact_models/userstory_artefact_model.py,sha256=xw1gsOjkAphd-4xwz5U6maZ6aASYn35_2DHCo1bPctA,6488
|
|
53
76
|
ara_cli/artefact_models/vision_artefact_model.py,sha256=frjaUJj-mmIlVHEhzAQztCGs-CtvNu_odSborgztfzo,5251
|
|
54
77
|
ara_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
78
|
ara_cli/commands/command.py,sha256=Y_2dNeuxRjbyI3ScXNv55lptSe8Hs_ya78L0nPYNZHA,154
|
|
56
79
|
ara_cli/commands/extract_command.py,sha256=CzUOwDembG587PYbxg5rge4XSfdsuTyOPUvkobkXCIs,573
|
|
57
80
|
ara_cli/commands/load_command.py,sha256=H3CfeHIL-criDU5oi4BONTSpyzJ4m8DzJ0ZCIiAZFeI,2204
|
|
58
81
|
ara_cli/commands/load_image_command.py,sha256=g9-PXAYdqx5Ed1PdVo-FIb4CyJGEpRFbgQf9Dxg6DmM,886
|
|
59
|
-
ara_cli/commands/read_command.py,sha256=
|
|
82
|
+
ara_cli/commands/read_command.py,sha256=xne8jlertuJNcsyzjR0bJeUUHi4NkEfd0h0DRbU9rC4,4347
|
|
60
83
|
ara_cli/file_loaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
84
|
ara_cli/file_loaders/binary_file_loader.py,sha256=1HHH1Nk4lEM83CTnf4z9wYz6rMLgpxydFoRcSgkBHmQ,940
|
|
62
85
|
ara_cli/file_loaders/document_file_loader.py,sha256=VxGFChYyM9K-e6eOCK3yk5jQuEXgz01Mh_NoA6CA_RM,1017
|
|
@@ -149,8 +172,8 @@ tests/test_artefact_link_updater.py,sha256=biqbEp2jCOz8giv72hu2P2hDfeJfJ9OrVGdAv
|
|
|
149
172
|
tests/test_artefact_lister.py,sha256=35R13UU-YsX1HOsEN8M2-vIiCUA9RSBm6SwestDaFhE,20388
|
|
150
173
|
tests/test_artefact_reader.py,sha256=660K-d8ed-j8hulsUB_7baPD2-hhbg9TffUR5yVc4Uo,927
|
|
151
174
|
tests/test_artefact_renamer.py,sha256=lSnKCCfoFGgKhTdDZrEaeBq1xJAak1QoqH5aSeOe9Ro,3494
|
|
152
|
-
tests/test_artefact_scan.py,sha256=
|
|
153
|
-
tests/test_chat.py,sha256=
|
|
175
|
+
tests/test_artefact_scan.py,sha256=SzMtJeh8_oOBec9yzy3vJRHxs9i1E5gEU2RfF6CJZqE,16888
|
|
176
|
+
tests/test_chat.py,sha256=D2HRRTdnvcDvB9TWz4O91ZONbLJL6w4v8TRTDwjtzzI,86104
|
|
154
177
|
tests/test_classifier.py,sha256=grYGPksydNdPsaEBQxYHZTuTdcJWz7VQtikCKA6BNaQ,1920
|
|
155
178
|
tests/test_directory_navigator.py,sha256=7G0MVrBbtBvbrFUpL0zb_9EkEWi1dulWuHsrQxMJxDY,140
|
|
156
179
|
tests/test_file_classifier.py,sha256=4O1C_iDpGGm35b7aI-HIJd5kkWxFUOrI2n4lEpiDNTM,11855
|
|
@@ -158,12 +181,13 @@ tests/test_file_creator.py,sha256=tgBCq6KPv-qMSDhj9AZvQIJABiAqgpFRnEg1fqbVrTI,20
|
|
|
158
181
|
tests/test_file_lister.py,sha256=Q9HwhKKx540EPzTmfzOCnvtAgON0aMmpJE2eOe1J3EA,4324
|
|
159
182
|
tests/test_global_file_lister.py,sha256=ycvf2YL8q5QSEMwcnQfUdoWnQQ8xTSyEtccAeXwl6QU,5487
|
|
160
183
|
tests/test_list_filter.py,sha256=fJA3d_SdaOAUkE7jn68MOVS0THXGghy1fye_64Zvo1U,7964
|
|
161
|
-
tests/test_prompt_handler.py,sha256=
|
|
162
|
-
tests/test_tag_extractor.py,sha256=
|
|
184
|
+
tests/test_prompt_handler.py,sha256=9s1zavcW81uz8wOBM_2X2KqdLNoc3E9bt0Oqt2-Sgmk,33926
|
|
185
|
+
tests/test_tag_extractor.py,sha256=7eVD10Y1uLkoSrEgqkXzRvPFs8lJ1RiaJzDu7ml_FZE,3118
|
|
186
|
+
tests/test_template_loader.py,sha256=R7s8HJZbKqja-1TRBMBkVKPTgajofUjjRKUJq7a3_Oc,7427
|
|
163
187
|
tests/test_template_manager.py,sha256=qliEeYgAEakn8JIqIHa8u0Ht6DY4L3T6DcHBXkjzR4I,4167
|
|
164
188
|
tests/test_update_config_prompt.py,sha256=xsqj1WTn4BsG5Q2t-sNPfu7EoMURFcS-hfb5VSXUnJc,6765
|
|
165
|
-
ara_cli-0.1.
|
|
166
|
-
ara_cli-0.1.
|
|
167
|
-
ara_cli-0.1.
|
|
168
|
-
ara_cli-0.1.
|
|
169
|
-
ara_cli-0.1.
|
|
189
|
+
ara_cli-0.1.10.1.dist-info/METADATA,sha256=-t9lEUM9L9Jf3Cc9LpgOqe8cSrcv2LMLe_qpTvV2aZU,6834
|
|
190
|
+
ara_cli-0.1.10.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
191
|
+
ara_cli-0.1.10.1.dist-info/entry_points.txt,sha256=v4h7MzysTgSIDYfEo3oj4Kz_8lzsRa3hq-KJHEcLVX8,45
|
|
192
|
+
ara_cli-0.1.10.1.dist-info/top_level.txt,sha256=WM4cLHT5DYUaWzLtRj-gu3yVNFpGQ6lLRI3FMmC-38I,14
|
|
193
|
+
ara_cli-0.1.10.1.dist-info/RECORD,,
|
tests/test_artefact_scan.py
CHANGED
|
@@ -132,7 +132,7 @@ def test_is_rule_valid_rule_is_none():
|
|
|
132
132
|
"parent,expected",
|
|
133
133
|
[
|
|
134
134
|
(None, True), # parent is None
|
|
135
|
-
(MagicMock(rules=None),
|
|
135
|
+
(MagicMock(rules=None), False), # parent.rules is None
|
|
136
136
|
],
|
|
137
137
|
)
|
|
138
138
|
def test_is_rule_valid_parent_or_rules_none(parent, expected):
|