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.

Files changed (48) hide show
  1. ara_cli/__init__.py +1 -1
  2. ara_cli/__main__.py +141 -103
  3. ara_cli/ara_command_action.py +65 -7
  4. ara_cli/ara_config.py +118 -94
  5. ara_cli/ara_subcommands/__init__.py +0 -0
  6. ara_cli/ara_subcommands/autofix.py +26 -0
  7. ara_cli/ara_subcommands/chat.py +27 -0
  8. ara_cli/ara_subcommands/classifier_directory.py +16 -0
  9. ara_cli/ara_subcommands/common.py +100 -0
  10. ara_cli/ara_subcommands/create.py +75 -0
  11. ara_cli/ara_subcommands/delete.py +22 -0
  12. ara_cli/ara_subcommands/extract.py +22 -0
  13. ara_cli/ara_subcommands/fetch_templates.py +14 -0
  14. ara_cli/ara_subcommands/list.py +65 -0
  15. ara_cli/ara_subcommands/list_tags.py +25 -0
  16. ara_cli/ara_subcommands/load.py +48 -0
  17. ara_cli/ara_subcommands/prompt.py +136 -0
  18. ara_cli/ara_subcommands/read.py +47 -0
  19. ara_cli/ara_subcommands/read_status.py +20 -0
  20. ara_cli/ara_subcommands/read_user.py +20 -0
  21. ara_cli/ara_subcommands/reconnect.py +27 -0
  22. ara_cli/ara_subcommands/rename.py +22 -0
  23. ara_cli/ara_subcommands/scan.py +14 -0
  24. ara_cli/ara_subcommands/set_status.py +22 -0
  25. ara_cli/ara_subcommands/set_user.py +22 -0
  26. ara_cli/ara_subcommands/template.py +16 -0
  27. ara_cli/artefact_models/artefact_model.py +88 -19
  28. ara_cli/artefact_models/artefact_templates.py +18 -9
  29. ara_cli/artefact_models/userstory_artefact_model.py +2 -2
  30. ara_cli/artefact_scan.py +2 -2
  31. ara_cli/chat.py +204 -142
  32. ara_cli/commands/read_command.py +17 -4
  33. ara_cli/completers.py +144 -0
  34. ara_cli/prompt_handler.py +268 -127
  35. ara_cli/tag_extractor.py +33 -16
  36. ara_cli/template_loader.py +245 -0
  37. ara_cli/version.py +1 -1
  38. {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/METADATA +3 -1
  39. {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/RECORD +47 -23
  40. tests/test_artefact_scan.py +1 -1
  41. tests/test_chat.py +1840 -574
  42. tests/test_prompt_handler.py +40 -4
  43. tests/test_tag_extractor.py +19 -13
  44. tests/test_template_loader.py +192 -0
  45. ara_cli/ara_command_parser.py +0 -565
  46. {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/WHEEL +0 -0
  47. {ara_cli-0.1.9.96.dist-info → ara_cli-0.1.10.1.dist-info}/entry_points.txt +0 -0
  48. {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, tags_set, filtered_artefacts):
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(tags_set, artefacts_to_process, status_tags)
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, tags_set, artefacts, status_tags):
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
- tags_set.add(tag)
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, tags_set, filtered_artefacts):
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
- tags = [
55
- tag
56
- for tag in (artefact.tags + [artefact.status] + user_tags)
57
- if tag is not None
58
- ]
59
- tags_set.update(tags)
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
- unique_tags = set()
102
+ tag_groups = {}
85
103
 
86
104
  if filtered_extra_column:
87
- self.filter_column(unique_tags, filtered_artefacts)
105
+ self.filter_column(tag_groups, filtered_artefacts)
88
106
  else:
89
- self.add_to_tags_set(unique_tags, filtered_artefacts)
107
+ self.add_to_tags_set(tag_groups, filtered_artefacts)
90
108
 
91
- sorted_tags = sorted(unique_tags)
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.9.96" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
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.9.96
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=Kozfk9i2DfbDi8GTkXjbqIoIxWXmbDhxb_edRv73oUU,495
2
- ara_cli/__main__.py,sha256=1GaJ2LJPOfAKZVPaKIkJ0x1L2p8yGMAgckzoRn_6JvA,3474
3
- ara_cli/ara_command_action.py,sha256=iPDiIaN60TEpVCnOT6Esestu0fNJFzbyhNENQytbkEo,22822
4
- ara_cli/ara_command_parser.py,sha256=A1lMc9Gc0EMJt-380PTcv3aKoxbXGfx5gGax-sZqV3I,21020
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=msPCm-vPWOAZ_e_z5GylXxq1MtNlmJ4zvKrsdOFCWF4,4813
15
- ara_cli/chat.py,sha256=SCllSt821naybvF6K4afJEtZvFZq7UO52O4fOm0Ieic,39859
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=8a9fcMwE_C6ntbw7UeroNJeU5LxrxEppiUtvYNUTB2U,23292
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=k2yRl7dAMZ4YTARzUke4wgY0oEIOmWkOHGet7nXB6uw,3317
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=-IPlzWGTvEOC2B1-l8hULGEXt1iWj3_npgirLamZr10,146
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=qSbcrmFWAYgBqcNl9QARI1_uLQJm-TPVgP5q2AEFnjE,15983
42
- ara_cli/artefact_models/artefact_templates.py,sha256=CFa_vIA-cnbZEHuACd24vNJB_7LueQi-8x7ga_AyLKI,9830
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=2awH31ROtm7j4T44Bv4cylQDYLQtnfgXZMhDu_pgw-k,6435
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=bo1BvRWuNKdFqBNN1EWORNrX_yuFAOyBruDUolHq1Vc,3791
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=uNWgrt7ieZ4ogKACsPqzAsh59JF2BhTKSag31hpVrTQ,16887
153
- tests/test_chat.py,sha256=UK1566DikkeXKzslw8h1it3UXqJEGLpxy02_Pch0Tfs,59433
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=kW8FU09ho4I5qC-f4G9r4ZgI-NlqdOkTmAazG7FaTrw,32299
162
- tests/test_tag_extractor.py,sha256=nSiAYlTKZ7TLAOtcJpwK5zTWHhFYU0tI5xKnivLc1dU,2712
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.9.96.dist-info/METADATA,sha256=rwUSTke0fhW8QCSyel4M0oASJkfy6AASVOkQMzdPBDo,6789
166
- ara_cli-0.1.9.96.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
167
- ara_cli-0.1.9.96.dist-info/entry_points.txt,sha256=v4h7MzysTgSIDYfEo3oj4Kz_8lzsRa3hq-KJHEcLVX8,45
168
- ara_cli-0.1.9.96.dist-info/top_level.txt,sha256=WM4cLHT5DYUaWzLtRj-gu3yVNFpGQ6lLRI3FMmC-38I,14
169
- ara_cli-0.1.9.96.dist-info/RECORD,,
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,,
@@ -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), True), # parent.rules is 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):