cloudwright-ai-cli 0.2.0__tar.gz → 0.2.2__tar.gz
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.
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/PKG-INFO +1 -1
- cloudwright_ai_cli-0.2.2/cloudwright_cli/__init__.py +1 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/analyze_cmd.py +8 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/catalog_cmd.py +32 -13
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/design.py +7 -1
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/modify_cmd.py +6 -1
- cloudwright_ai_cli-0.2.0/cloudwright_cli/__init__.py +0 -1
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/.gitignore +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/CLAUDE.md +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/README.md +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/__main__.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/__init__.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/chat.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/compare.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/cost.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/diff.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/drift_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/export.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/import_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/init_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/lint_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/policy.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/refresh_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/score_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/validate.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/main.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/project.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/py.typed +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/utils.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/pyproject.toml +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/tests/__init__.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/tests/test_cli.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/tests/test_drift_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/tests/test_init.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/tests/test_modify_cmd.py +0 -0
- {cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/tests/test_project.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudwright-ai-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: CLI for Cloudwright architecture intelligence
|
|
5
5
|
Project-URL: Homepage, https://github.com/xmpuspus/cloudwright
|
|
6
6
|
Project-URL: Repository, https://github.com/xmpuspus/cloudwright
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.2"
|
{cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/analyze_cmd.py
RENAMED
|
@@ -27,6 +27,14 @@ def analyze(
|
|
|
27
27
|
from cloudwright.analyzer import Analyzer
|
|
28
28
|
|
|
29
29
|
spec = ArchSpec.from_file(spec_file)
|
|
30
|
+
|
|
31
|
+
if component:
|
|
32
|
+
valid_ids = {c.id for c in spec.components}
|
|
33
|
+
if component not in valid_ids:
|
|
34
|
+
console.print(f"[red]Error:[/red] Component '{component}' not found in spec.")
|
|
35
|
+
console.print(f"[dim]Available components: {', '.join(sorted(valid_ids))}[/dim]")
|
|
36
|
+
raise typer.Exit(1)
|
|
37
|
+
|
|
30
38
|
analyzer = Analyzer()
|
|
31
39
|
result = analyzer.analyze(spec, component_id=component)
|
|
32
40
|
|
{cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/catalog_cmd.py
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import re
|
|
3
4
|
from typing import Annotated
|
|
4
5
|
|
|
5
6
|
import typer
|
|
@@ -34,16 +35,33 @@ def catalog_search(
|
|
|
34
35
|
memory: Annotated[float | None, typer.Option(help="Minimum memory in GB")] = None,
|
|
35
36
|
) -> None:
|
|
36
37
|
"""Search the cloud service catalog."""
|
|
37
|
-
filters
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if
|
|
43
|
-
|
|
38
|
+
# Extract structured filters from natural language query
|
|
39
|
+
parsed_vcpus = vcpus
|
|
40
|
+
parsed_memory = memory
|
|
41
|
+
text_query = query
|
|
42
|
+
|
|
43
|
+
if parsed_vcpus is None:
|
|
44
|
+
m = re.search(r"(\d+)\s*vcpu", query, re.IGNORECASE)
|
|
45
|
+
if m:
|
|
46
|
+
parsed_vcpus = int(m.group(1))
|
|
47
|
+
text_query = re.sub(r"\d+\s*vcpus?\s*", "", text_query, flags=re.IGNORECASE).strip()
|
|
48
|
+
|
|
49
|
+
if parsed_memory is None:
|
|
50
|
+
m = re.search(r"(\d+(?:\.\d+)?)\s*(?:gb|gib)\s*(?:memory|ram)?", query, re.IGNORECASE)
|
|
51
|
+
if m:
|
|
52
|
+
parsed_memory = float(m.group(1))
|
|
53
|
+
text_query = re.sub(r"\d+(?:\.\d+)?\s*(?:gb|gib)\s*(?:memory|ram)?\s*", "", text_query, flags=re.IGNORECASE).strip()
|
|
54
|
+
|
|
55
|
+
# Clean up leftover whitespace/empty query
|
|
56
|
+
text_query = text_query.strip() or None
|
|
44
57
|
|
|
45
58
|
with console.status("Searching catalog..."):
|
|
46
|
-
results = Catalog().search(
|
|
59
|
+
results = Catalog().search(
|
|
60
|
+
query=text_query,
|
|
61
|
+
vcpus=parsed_vcpus,
|
|
62
|
+
memory_gb=parsed_memory,
|
|
63
|
+
provider=provider,
|
|
64
|
+
)
|
|
47
65
|
|
|
48
66
|
# Resolve ctx.obj through parent chain when invoked via sub-app
|
|
49
67
|
obj = ctx.obj or (ctx.parent.obj if ctx.parent else None)
|
|
@@ -67,14 +85,15 @@ def catalog_search(
|
|
|
67
85
|
table.add_column("Notes", style="dim")
|
|
68
86
|
|
|
69
87
|
for item in results:
|
|
88
|
+
price = item.get("price_per_hour")
|
|
70
89
|
table.add_row(
|
|
71
|
-
item.get("
|
|
72
|
-
item.get("
|
|
73
|
-
item.get("
|
|
90
|
+
item.get("name", ""),
|
|
91
|
+
item.get("provider_id", ""),
|
|
92
|
+
item.get("family", ""),
|
|
74
93
|
str(item.get("vcpus", "-")),
|
|
75
94
|
str(item.get("memory_gb", "-")),
|
|
76
|
-
f"${
|
|
77
|
-
item.get("
|
|
95
|
+
f"${price:.4f}" if price else "-",
|
|
96
|
+
item.get("description", ""),
|
|
78
97
|
)
|
|
79
98
|
|
|
80
99
|
console.print(table)
|
|
@@ -35,8 +35,14 @@ def design(
|
|
|
35
35
|
compliance=compliance or [],
|
|
36
36
|
)
|
|
37
37
|
|
|
38
|
+
try:
|
|
39
|
+
architect = Architect()
|
|
40
|
+
except RuntimeError as e:
|
|
41
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
42
|
+
raise typer.Exit(1) from None
|
|
43
|
+
|
|
38
44
|
with console.status("Designing architecture..."):
|
|
39
|
-
spec =
|
|
45
|
+
spec = architect.design(description, constraints=constraints)
|
|
40
46
|
# Set provider/region from CLI args if not overridden by LLM
|
|
41
47
|
if spec.provider == "aws" and provider != "aws":
|
|
42
48
|
spec = spec.model_copy(update={"provider": provider})
|
{cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/modify_cmd.py
RENAMED
|
@@ -40,8 +40,13 @@ def modify(
|
|
|
40
40
|
|
|
41
41
|
console.print(f"Modifying [cyan]{spec_file}[/cyan]: [yellow]{instruction}[/yellow]\n")
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
try:
|
|
44
44
|
architect = Architect()
|
|
45
|
+
except RuntimeError as e:
|
|
46
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
47
|
+
raise typer.Exit(1) from None
|
|
48
|
+
|
|
49
|
+
with console.status("Applying modification..."):
|
|
45
50
|
modified = architect.modify(original, instruction)
|
|
46
51
|
|
|
47
52
|
# Price both versions; ignore errors (catalog may not have all services)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/import_cmd.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudwright_ai_cli-0.2.0 → cloudwright_ai_cli-0.2.2}/cloudwright_cli/commands/refresh_cmd.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|