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
@@ -30,6 +30,11 @@ class ReadCommand(Command):
30
30
  """Execute the read command and return success status."""
31
31
  file_classifier = FileClassifier(os)
32
32
  classified_artefacts = ArtefactReader.read_artefacts()
33
+
34
+ if not self.classifier or not self.artefact_name:
35
+ self._filter_and_print(classified_artefacts, file_classifier)
36
+ return True
37
+
33
38
  artefacts = classified_artefacts.get(self.classifier, [])
34
39
  all_artefact_names = [a.title for a in artefacts]
35
40
 
@@ -62,10 +67,11 @@ class ReadCommand(Command):
62
67
  )
63
68
 
64
69
  # Apply filtering and print results
65
- filtered_artefacts = self._apply_filtering(artefacts_by_classifier)
66
- file_classifier.print_classified_files(
67
- filtered_artefacts, print_content=True
68
- )
70
+ self._filter_and_print(artefacts_by_classifier, file_classifier)
71
+ # filtered_artefacts = self._apply_filtering(artefacts_by_classifier)
72
+ # file_classifier.print_classified_files(
73
+ # filtered_artefacts, print_content=True
74
+ # )
69
75
  return True
70
76
 
71
77
  except Exception as e:
@@ -102,3 +108,10 @@ class ReadCommand(Command):
102
108
  file_path_retrieval=artefact_path_retrieval,
103
109
  tag_retrieval=artefact_tags_retrieval
104
110
  )
111
+
112
+ def _filter_and_print(self, artefacts_by_classifier, file_classifier):
113
+ """Apply list filtering and print results"""
114
+ filtered_artefacts = self._apply_filtering(artefacts_by_classifier)
115
+ file_classifier.print_classified_files(
116
+ filtered_artefacts, print_content=True
117
+ )
ara_cli/completers.py ADDED
@@ -0,0 +1,144 @@
1
+ import os
2
+ from typing import List, Optional
3
+ from pathlib import Path
4
+ import typer
5
+
6
+ from ara_cli.classifier import Classifier
7
+ from ara_cli.template_manager import SpecificationBreakdownAspects
8
+
9
+
10
+ def complete_classifier(incomplete: str) -> List[str]:
11
+ """Complete classifier names."""
12
+ classifiers = Classifier.ordered_classifiers()
13
+ return [c for c in classifiers if c.startswith(incomplete)]
14
+
15
+
16
+ def complete_aspect(incomplete: str) -> List[str]:
17
+ """Complete aspect names."""
18
+ aspects = SpecificationBreakdownAspects.VALID_ASPECTS
19
+ return [a for a in aspects if a.startswith(incomplete)]
20
+
21
+
22
+ def complete_status(incomplete: str) -> List[str]:
23
+ """Complete task status values."""
24
+ statuses = ["to-do", "in-progress", "review", "done", "closed"]
25
+ return [s for s in statuses if s.startswith(incomplete)]
26
+
27
+
28
+ def complete_template_type(incomplete: str) -> List[str]:
29
+ """Complete template type values."""
30
+ template_types = ["rules", "intention", "commands", "blueprint"]
31
+ return [t for t in template_types if t.startswith(incomplete)]
32
+
33
+
34
+ def complete_artefact_name(classifier: str) -> List[str]:
35
+ """Complete artefact names for a given classifier."""
36
+ try:
37
+ # Get the directory for the classifier
38
+ classifier_dir = f"ara/{Classifier.get_sub_directory(classifier)}"
39
+
40
+ if not os.path.exists(classifier_dir):
41
+ return []
42
+
43
+ # Find all files with the classifier extension
44
+ artefacts = []
45
+ for file in os.listdir(classifier_dir):
46
+ if file.endswith(f'.{classifier}'):
47
+ # Remove the extension to get the artefact name
48
+ name = file[:-len(f'.{classifier}')]
49
+ artefacts.append(name)
50
+
51
+ return sorted(artefacts)
52
+ except Exception:
53
+ return []
54
+
55
+
56
+ def complete_artefact_name_for_classifier(classifier: str):
57
+ """Create a completer function for artefact names of a specific classifier."""
58
+ def completer(incomplete: str) -> List[str]:
59
+ artefacts = complete_artefact_name(classifier)
60
+ return [a for a in artefacts if a.startswith(incomplete)]
61
+ return completer
62
+
63
+
64
+ def complete_chat_files(incomplete: str) -> List[str]:
65
+ """Complete chat file names (without .md extension)."""
66
+ try:
67
+ chat_files = []
68
+ current_dir = Path.cwd()
69
+
70
+ # Look for .md files in current directory
71
+ for file in current_dir.glob("*.md"):
72
+ name = file.stem
73
+ if name.startswith(incomplete):
74
+ chat_files.append(name)
75
+
76
+ return sorted(chat_files)
77
+ except Exception:
78
+ return []
79
+
80
+
81
+ # Dynamic completers that need context
82
+ class DynamicCompleters:
83
+ @staticmethod
84
+ def create_classifier_completer():
85
+ """Create a completer for classifiers."""
86
+ def completer(ctx: typer.Context, incomplete: str) -> List[str]:
87
+ return complete_classifier(incomplete)
88
+ return completer
89
+
90
+ @staticmethod
91
+ def create_aspect_completer():
92
+ """Create a completer for aspects."""
93
+ def completer(ctx: typer.Context, incomplete: str) -> List[str]:
94
+ return complete_aspect(incomplete)
95
+ return completer
96
+
97
+ @staticmethod
98
+ def create_status_completer():
99
+ """Create a completer for status values."""
100
+ def completer(ctx: typer.Context, incomplete: str) -> List[str]:
101
+ return complete_status(incomplete)
102
+ return completer
103
+
104
+ @staticmethod
105
+ def create_template_type_completer():
106
+ """Create a completer for template types."""
107
+ def completer(ctx: typer.Context, incomplete: str) -> List[str]:
108
+ return complete_template_type(incomplete)
109
+ return completer
110
+
111
+ @staticmethod
112
+ def create_artefact_name_completer():
113
+ """Create a completer for artefact names based on classifier context."""
114
+ def completer(ctx: typer.Context, incomplete: str) -> List[str]:
115
+ # Try to get classifier from context
116
+ if hasattr(ctx, 'params') and 'classifier' in ctx.params:
117
+ classifier = ctx.params['classifier']
118
+ if hasattr(classifier, 'value'):
119
+ classifier = classifier.value
120
+ artefacts = complete_artefact_name(classifier)
121
+ return [a for a in artefacts if a.startswith(incomplete)]
122
+ return []
123
+ return completer
124
+
125
+ @staticmethod
126
+ def create_parent_name_completer():
127
+ """Create a completer for parent artefact names based on parent classifier context."""
128
+ def completer(ctx: typer.Context, incomplete: str) -> List[str]:
129
+ # Try to get parent_classifier from context
130
+ if hasattr(ctx, 'params') and 'parent_classifier' in ctx.params:
131
+ parent_classifier = ctx.params['parent_classifier']
132
+ if hasattr(parent_classifier, 'value'):
133
+ parent_classifier = parent_classifier.value
134
+ artefacts = complete_artefact_name(parent_classifier)
135
+ return [a for a in artefacts if a.startswith(incomplete)]
136
+ return []
137
+ return completer
138
+
139
+ @staticmethod
140
+ def create_chat_file_completer():
141
+ """Create a completer for chat files."""
142
+ def completer(ctx: typer.Context, incomplete: str) -> List[str]:
143
+ return complete_chat_files(incomplete)
144
+ return completer