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/commands/read_command.py
CHANGED
|
@@ -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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|