inframate 0.1.0__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.
- inframate-0.1.0/PKG-INFO +182 -0
- inframate-0.1.0/README.md +161 -0
- inframate-0.1.0/app/__init__.py +0 -0
- inframate-0.1.0/app/cli.py +81 -0
- inframate-0.1.0/app/cli_commands/__init__.py +0 -0
- inframate-0.1.0/app/cli_commands/console.py +17 -0
- inframate-0.1.0/app/cli_commands/resources.py +476 -0
- inframate-0.1.0/app/cli_commands/resources_tui.py +649 -0
- inframate-0.1.0/app/cli_commands/ui.py +17 -0
- inframate-0.1.0/app/config.py +111 -0
- inframate-0.1.0/app/main.py +47 -0
- inframate-0.1.0/app/routers/__init__.py +0 -0
- inframate-0.1.0/app/routers/ai.py +52 -0
- inframate-0.1.0/app/routers/terraform.py +391 -0
- inframate-0.1.0/app/schemas.py +29 -0
- inframate-0.1.0/app/services/__init__.py +0 -0
- inframate-0.1.0/app/services/ai_service.py +143 -0
- inframate-0.1.0/app/services/aws_costs.py +324 -0
- inframate-0.1.0/app/services/aws_delete.py +365 -0
- inframate-0.1.0/app/services/aws_inventory.py +711 -0
- inframate-0.1.0/app/services/aws_resources.py +203 -0
- inframate-0.1.0/app/services/aws_service.py +211 -0
- inframate-0.1.0/app/services/backend_check.py +222 -0
- inframate-0.1.0/app/services/overview.py +278 -0
- inframate-0.1.0/app/services/plan_cache.py +68 -0
- inframate-0.1.0/app/services/terraform_cli.py +167 -0
- inframate-0.1.0/app/services/terraform_parser.py +358 -0
- inframate-0.1.0/app/services/unified.py +141 -0
- inframate-0.1.0/app/services/version_check.py +92 -0
- inframate-0.1.0/app/static/assets/index-BzFAChWs.js +564 -0
- inframate-0.1.0/app/static/assets/index-DBlYBuju.css +1 -0
- inframate-0.1.0/app/static/index.html +13 -0
- inframate-0.1.0/inframate.egg-info/PKG-INFO +182 -0
- inframate-0.1.0/inframate.egg-info/SOURCES.txt +38 -0
- inframate-0.1.0/inframate.egg-info/dependency_links.txt +1 -0
- inframate-0.1.0/inframate.egg-info/entry_points.txt +2 -0
- inframate-0.1.0/inframate.egg-info/requires.txt +8 -0
- inframate-0.1.0/inframate.egg-info/top_level.txt +2 -0
- inframate-0.1.0/pyproject.toml +42 -0
- inframate-0.1.0/setup.cfg +4 -0
inframate-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: inframate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An all-in-one local interface for navigating, operating, and understanding your Terraform infrastructure
|
|
5
|
+
Author: Amin Dorostanian
|
|
6
|
+
License-Expression: AGPL-3.0-only
|
|
7
|
+
Project-URL: Homepage, https://github.com/neuroship/inframate
|
|
8
|
+
Project-URL: Repository, https://github.com/neuroship/inframate
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Framework :: FastAPI
|
|
11
|
+
Requires-Python: >=3.13
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: fastapi[standard]>=0.115.0
|
|
14
|
+
Requires-Dist: python-hcl2>=5.0
|
|
15
|
+
Requires-Dist: openai>=1.50
|
|
16
|
+
Requires-Dist: python-dotenv>=1.0
|
|
17
|
+
Requires-Dist: aioboto3>=15.5.0
|
|
18
|
+
Requires-Dist: pyyaml>=6.0
|
|
19
|
+
Requires-Dist: rich>=15.0.0
|
|
20
|
+
Requires-Dist: textual>=8.2.3
|
|
21
|
+
|
|
22
|
+
# inframate
|
|
23
|
+
|
|
24
|
+
A CLI tool for managing Terraform infrastructure. Browse resources, apply changes, detect drift, view costs, and fix errors with AI — all from your terminal.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# uv (recommended)
|
|
30
|
+
uv tool install inframate
|
|
31
|
+
|
|
32
|
+
# Homebrew
|
|
33
|
+
brew install inframate
|
|
34
|
+
|
|
35
|
+
# pip / pipx
|
|
36
|
+
pip install inframate
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
cd my-terraform-project
|
|
43
|
+
inframate # interactive resource browser (TUI)
|
|
44
|
+
inframate --no-cloud # skip AWS cloud scan (faster)
|
|
45
|
+
inframate --service s3 # filter by service
|
|
46
|
+
inframate --json # output as JSON
|
|
47
|
+
inframate serve # start web UI at http://localhost:8000
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Running `inframate` in a Terraform project directory will:
|
|
51
|
+
|
|
52
|
+
1. Read the Terraform graph and plan
|
|
53
|
+
2. Scan AWS resources for drift and unmanaged resources
|
|
54
|
+
3. Open an interactive TUI for browsing, applying, and destroying resources
|
|
55
|
+
4. If the plan fails and AI is configured, offer AI-assisted diagnosis and fixes
|
|
56
|
+
|
|
57
|
+
### Resource statuses
|
|
58
|
+
|
|
59
|
+
| Status | Meaning |
|
|
60
|
+
|--------|---------|
|
|
61
|
+
| **Managed** | In Terraform state and code, no pending changes |
|
|
62
|
+
| **Pending** | In code but not yet applied (create/update/destroy/replace planned) |
|
|
63
|
+
| **Drift** | Applied but actual cloud state differs from Terraform state |
|
|
64
|
+
| **Unmanaged** | Exists in AWS but not in any Terraform configuration |
|
|
65
|
+
| **Orphaned** | In Terraform state but the resource no longer exists in cloud |
|
|
66
|
+
|
|
67
|
+
Each resource also shows three indicators: **S** (in state), **C** (in code), **W** (in cloud).
|
|
68
|
+
|
|
69
|
+
### TUI keybindings
|
|
70
|
+
|
|
71
|
+
**Navigation & search**
|
|
72
|
+
|
|
73
|
+
| Key | Action |
|
|
74
|
+
|-----|--------|
|
|
75
|
+
| `Up/Down` | Navigate resources |
|
|
76
|
+
| `Left/Right` | Collapse/expand tree node |
|
|
77
|
+
| `/` | Search resources by name, type, or service |
|
|
78
|
+
| `Escape` | Clear search |
|
|
79
|
+
| `e` | Expand all tree nodes |
|
|
80
|
+
| `c` | Collapse all tree nodes |
|
|
81
|
+
|
|
82
|
+
**Filters**
|
|
83
|
+
|
|
84
|
+
| Key | Action |
|
|
85
|
+
|-----|--------|
|
|
86
|
+
| `a` | Show all resources |
|
|
87
|
+
| `m` | Filter: managed |
|
|
88
|
+
| `p` | Filter: pending |
|
|
89
|
+
| `d` | Filter: drift |
|
|
90
|
+
| `u` | Filter: unmanaged |
|
|
91
|
+
| `o` | Filter: orphaned |
|
|
92
|
+
| `1` | Filter action: create |
|
|
93
|
+
| `2` | Filter action: update |
|
|
94
|
+
| `3` | Filter action: destroy |
|
|
95
|
+
| `4` | Filter action: replace |
|
|
96
|
+
| `0` | Clear action filter |
|
|
97
|
+
|
|
98
|
+
**Actions**
|
|
99
|
+
|
|
100
|
+
| Key | Action |
|
|
101
|
+
|-----|--------|
|
|
102
|
+
| `Enter` | Show resource detail (attributes, changes, tags) |
|
|
103
|
+
| `Space` | Toggle resource selection |
|
|
104
|
+
| `r` | Apply (all planned changes, or selected only) |
|
|
105
|
+
| `x` | Destroy selected resources |
|
|
106
|
+
| `$` | Load and display AWS costs |
|
|
107
|
+
| `F5` | Refresh (re-read terraform + cloud data) |
|
|
108
|
+
| `q` | Quit |
|
|
109
|
+
|
|
110
|
+
When apply or destroy fails, inframate streams AI diagnosis, suggests file changes and commands (e.g. `terraform import`, `terraform state rm`), and offers to apply fixes — in a loop until the issue is resolved.
|
|
111
|
+
|
|
112
|
+
## Configuration
|
|
113
|
+
|
|
114
|
+
Config is stored in `~/.inframate/config.yml` (created on first run). Project-level `.inframate.yml` overrides global settings.
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
ai:
|
|
118
|
+
provider: openai # openai | anthropic | ollama | groq | deepseek
|
|
119
|
+
api_token: sk-...
|
|
120
|
+
# model: gpt-4o # optional, defaults per provider
|
|
121
|
+
|
|
122
|
+
# Or use a custom endpoint:
|
|
123
|
+
# ai:
|
|
124
|
+
# endpoint: http://localhost:11434/v1
|
|
125
|
+
# api_token: ollama
|
|
126
|
+
# model: llama3
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Provider defaults:
|
|
130
|
+
|
|
131
|
+
| Provider | Endpoint | Default model |
|
|
132
|
+
|----------|----------|---------------|
|
|
133
|
+
| `openai` | `api.openai.com/v1` | `gpt-4o` |
|
|
134
|
+
| `anthropic` | `api.anthropic.com/v1` | `claude-sonnet-4-20250514` |
|
|
135
|
+
| `ollama` | `localhost:11434/v1` | `llama3` |
|
|
136
|
+
| `groq` | `api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
|
|
137
|
+
| `deepseek` | `api.deepseek.com/v1` | `deepseek-chat` |
|
|
138
|
+
|
|
139
|
+
Environment variables (`OPENAI_API_KEY`, `OPENAI_API_BASE`, `OPENAI_MODEL`) also work and take precedence over the config file.
|
|
140
|
+
|
|
141
|
+
## Web UI
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
inframate serve
|
|
145
|
+
inframate serve --port 9000
|
|
146
|
+
inframate serve --no-browser
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The web UI provides a browser-based interface with file editing, AI chat sidebar, and interactive resource management.
|
|
150
|
+
|
|
151
|
+
## Development
|
|
152
|
+
|
|
153
|
+
### Prerequisites
|
|
154
|
+
|
|
155
|
+
- [go-task](https://taskfile.dev/)
|
|
156
|
+
- [Python 3.13+](https://www.python.org/)
|
|
157
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
158
|
+
- [Node.js 22+](https://nodejs.org/)
|
|
159
|
+
- [Terraform](https://www.terraform.io/)
|
|
160
|
+
|
|
161
|
+
### Setup
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
task install # install all dependencies
|
|
165
|
+
task api:dev # start API server (terminal 1)
|
|
166
|
+
task ui:dev # start UI dev server (terminal 2)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Build
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
task build # build UI + Python package
|
|
173
|
+
task run # run the built CLI
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Project structure
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
services/
|
|
180
|
+
api/ Python 3.13 / FastAPI backend
|
|
181
|
+
ui/ Svelte 5 / TailwindCSS frontend
|
|
182
|
+
```
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# inframate
|
|
2
|
+
|
|
3
|
+
A CLI tool for managing Terraform infrastructure. Browse resources, apply changes, detect drift, view costs, and fix errors with AI — all from your terminal.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# uv (recommended)
|
|
9
|
+
uv tool install inframate
|
|
10
|
+
|
|
11
|
+
# Homebrew
|
|
12
|
+
brew install inframate
|
|
13
|
+
|
|
14
|
+
# pip / pipx
|
|
15
|
+
pip install inframate
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cd my-terraform-project
|
|
22
|
+
inframate # interactive resource browser (TUI)
|
|
23
|
+
inframate --no-cloud # skip AWS cloud scan (faster)
|
|
24
|
+
inframate --service s3 # filter by service
|
|
25
|
+
inframate --json # output as JSON
|
|
26
|
+
inframate serve # start web UI at http://localhost:8000
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Running `inframate` in a Terraform project directory will:
|
|
30
|
+
|
|
31
|
+
1. Read the Terraform graph and plan
|
|
32
|
+
2. Scan AWS resources for drift and unmanaged resources
|
|
33
|
+
3. Open an interactive TUI for browsing, applying, and destroying resources
|
|
34
|
+
4. If the plan fails and AI is configured, offer AI-assisted diagnosis and fixes
|
|
35
|
+
|
|
36
|
+
### Resource statuses
|
|
37
|
+
|
|
38
|
+
| Status | Meaning |
|
|
39
|
+
|--------|---------|
|
|
40
|
+
| **Managed** | In Terraform state and code, no pending changes |
|
|
41
|
+
| **Pending** | In code but not yet applied (create/update/destroy/replace planned) |
|
|
42
|
+
| **Drift** | Applied but actual cloud state differs from Terraform state |
|
|
43
|
+
| **Unmanaged** | Exists in AWS but not in any Terraform configuration |
|
|
44
|
+
| **Orphaned** | In Terraform state but the resource no longer exists in cloud |
|
|
45
|
+
|
|
46
|
+
Each resource also shows three indicators: **S** (in state), **C** (in code), **W** (in cloud).
|
|
47
|
+
|
|
48
|
+
### TUI keybindings
|
|
49
|
+
|
|
50
|
+
**Navigation & search**
|
|
51
|
+
|
|
52
|
+
| Key | Action |
|
|
53
|
+
|-----|--------|
|
|
54
|
+
| `Up/Down` | Navigate resources |
|
|
55
|
+
| `Left/Right` | Collapse/expand tree node |
|
|
56
|
+
| `/` | Search resources by name, type, or service |
|
|
57
|
+
| `Escape` | Clear search |
|
|
58
|
+
| `e` | Expand all tree nodes |
|
|
59
|
+
| `c` | Collapse all tree nodes |
|
|
60
|
+
|
|
61
|
+
**Filters**
|
|
62
|
+
|
|
63
|
+
| Key | Action |
|
|
64
|
+
|-----|--------|
|
|
65
|
+
| `a` | Show all resources |
|
|
66
|
+
| `m` | Filter: managed |
|
|
67
|
+
| `p` | Filter: pending |
|
|
68
|
+
| `d` | Filter: drift |
|
|
69
|
+
| `u` | Filter: unmanaged |
|
|
70
|
+
| `o` | Filter: orphaned |
|
|
71
|
+
| `1` | Filter action: create |
|
|
72
|
+
| `2` | Filter action: update |
|
|
73
|
+
| `3` | Filter action: destroy |
|
|
74
|
+
| `4` | Filter action: replace |
|
|
75
|
+
| `0` | Clear action filter |
|
|
76
|
+
|
|
77
|
+
**Actions**
|
|
78
|
+
|
|
79
|
+
| Key | Action |
|
|
80
|
+
|-----|--------|
|
|
81
|
+
| `Enter` | Show resource detail (attributes, changes, tags) |
|
|
82
|
+
| `Space` | Toggle resource selection |
|
|
83
|
+
| `r` | Apply (all planned changes, or selected only) |
|
|
84
|
+
| `x` | Destroy selected resources |
|
|
85
|
+
| `$` | Load and display AWS costs |
|
|
86
|
+
| `F5` | Refresh (re-read terraform + cloud data) |
|
|
87
|
+
| `q` | Quit |
|
|
88
|
+
|
|
89
|
+
When apply or destroy fails, inframate streams AI diagnosis, suggests file changes and commands (e.g. `terraform import`, `terraform state rm`), and offers to apply fixes — in a loop until the issue is resolved.
|
|
90
|
+
|
|
91
|
+
## Configuration
|
|
92
|
+
|
|
93
|
+
Config is stored in `~/.inframate/config.yml` (created on first run). Project-level `.inframate.yml` overrides global settings.
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
ai:
|
|
97
|
+
provider: openai # openai | anthropic | ollama | groq | deepseek
|
|
98
|
+
api_token: sk-...
|
|
99
|
+
# model: gpt-4o # optional, defaults per provider
|
|
100
|
+
|
|
101
|
+
# Or use a custom endpoint:
|
|
102
|
+
# ai:
|
|
103
|
+
# endpoint: http://localhost:11434/v1
|
|
104
|
+
# api_token: ollama
|
|
105
|
+
# model: llama3
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Provider defaults:
|
|
109
|
+
|
|
110
|
+
| Provider | Endpoint | Default model |
|
|
111
|
+
|----------|----------|---------------|
|
|
112
|
+
| `openai` | `api.openai.com/v1` | `gpt-4o` |
|
|
113
|
+
| `anthropic` | `api.anthropic.com/v1` | `claude-sonnet-4-20250514` |
|
|
114
|
+
| `ollama` | `localhost:11434/v1` | `llama3` |
|
|
115
|
+
| `groq` | `api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
|
|
116
|
+
| `deepseek` | `api.deepseek.com/v1` | `deepseek-chat` |
|
|
117
|
+
|
|
118
|
+
Environment variables (`OPENAI_API_KEY`, `OPENAI_API_BASE`, `OPENAI_MODEL`) also work and take precedence over the config file.
|
|
119
|
+
|
|
120
|
+
## Web UI
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
inframate serve
|
|
124
|
+
inframate serve --port 9000
|
|
125
|
+
inframate serve --no-browser
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The web UI provides a browser-based interface with file editing, AI chat sidebar, and interactive resource management.
|
|
129
|
+
|
|
130
|
+
## Development
|
|
131
|
+
|
|
132
|
+
### Prerequisites
|
|
133
|
+
|
|
134
|
+
- [go-task](https://taskfile.dev/)
|
|
135
|
+
- [Python 3.13+](https://www.python.org/)
|
|
136
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
137
|
+
- [Node.js 22+](https://nodejs.org/)
|
|
138
|
+
- [Terraform](https://www.terraform.io/)
|
|
139
|
+
|
|
140
|
+
### Setup
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
task install # install all dependencies
|
|
144
|
+
task api:dev # start API server (terminal 1)
|
|
145
|
+
task ui:dev # start UI dev server (terminal 2)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Build
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
task build # build UI + Python package
|
|
152
|
+
task run # run the built CLI
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Project structure
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
services/
|
|
159
|
+
api/ Python 3.13 / FastAPI backend
|
|
160
|
+
ui/ Svelte 5 / TailwindCSS frontend
|
|
161
|
+
```
|
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def _check_tf_files(project_dir: str):
|
|
6
|
+
has_tf = any(f.endswith(".tf") for f in os.listdir(project_dir) if os.path.isfile(os.path.join(project_dir, f)))
|
|
7
|
+
if not has_tf:
|
|
8
|
+
print(f"No .tf files found in {project_dir}")
|
|
9
|
+
print()
|
|
10
|
+
print("To get started, create a terraform configuration or run:")
|
|
11
|
+
print(f" cd {project_dir} && terraform init")
|
|
12
|
+
raise SystemExit(1)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def main():
|
|
16
|
+
parser = argparse.ArgumentParser(
|
|
17
|
+
prog="inframate",
|
|
18
|
+
description="Terraform infrastructure management tool. Runs the interactive resource browser by default.",
|
|
19
|
+
)
|
|
20
|
+
parser.add_argument("--dir", type=str, default=".", help="Terraform project directory (default: cwd)")
|
|
21
|
+
parser.add_argument("--service", type=str, default=None, help="Filter by service name")
|
|
22
|
+
parser.add_argument("--no-cloud", action="store_true", help="Skip cloud scan (faster, no drift/unmanaged detection)")
|
|
23
|
+
parser.add_argument("--status", type=str, default=None, choices=["managed", "pending", "drift", "unmanaged", "orphaned"], help="Filter by status (for --json)")
|
|
24
|
+
parser.add_argument("--json", action="store_true", dest="json_output", help="Output as JSON (non-interactive)")
|
|
25
|
+
|
|
26
|
+
sub = parser.add_subparsers(dest="command")
|
|
27
|
+
|
|
28
|
+
ui_parser = sub.add_parser("serve", help="Start web server with UI")
|
|
29
|
+
ui_parser.add_argument("--port", type=int, default=None, help="Port (default: from config or 8000)")
|
|
30
|
+
ui_parser.add_argument("--no-browser", action="store_true", help="Don't open browser on startup")
|
|
31
|
+
|
|
32
|
+
args = parser.parse_args()
|
|
33
|
+
|
|
34
|
+
project_dir = os.path.abspath(args.dir)
|
|
35
|
+
if not os.path.isdir(project_dir):
|
|
36
|
+
print(f"Error: {project_dir} is not a directory")
|
|
37
|
+
raise SystemExit(1)
|
|
38
|
+
|
|
39
|
+
# Version check (background)
|
|
40
|
+
from app.services.version_check import start_check, print_update_notice
|
|
41
|
+
version_thread = start_check()
|
|
42
|
+
|
|
43
|
+
# Load config
|
|
44
|
+
from app import config
|
|
45
|
+
overrides = {}
|
|
46
|
+
if hasattr(args, "port") and args.port is not None:
|
|
47
|
+
overrides["port"] = args.port
|
|
48
|
+
config.init_config_dir()
|
|
49
|
+
config.load_config(project_dir, overrides)
|
|
50
|
+
|
|
51
|
+
_check_tf_files(project_dir)
|
|
52
|
+
|
|
53
|
+
# Backend reachability check (skip for ui)
|
|
54
|
+
credential_expiry = None
|
|
55
|
+
if args.command != "serve":
|
|
56
|
+
from app.services.backend_check import check_backend, get_credential_expiry
|
|
57
|
+
ok, errors = check_backend(project_dir)
|
|
58
|
+
if not ok:
|
|
59
|
+
print("Backend authentication failed:\n")
|
|
60
|
+
for err in errors:
|
|
61
|
+
print(f" - {err}")
|
|
62
|
+
print()
|
|
63
|
+
raise SystemExit(1)
|
|
64
|
+
credential_expiry = get_credential_expiry()
|
|
65
|
+
|
|
66
|
+
# Dispatch
|
|
67
|
+
try:
|
|
68
|
+
if args.command == "serve":
|
|
69
|
+
from app.cli_commands.ui import run_ui
|
|
70
|
+
run_ui(project_dir, config.get_port(), args.no_browser)
|
|
71
|
+
else:
|
|
72
|
+
from app.cli_commands.resources import run_resources
|
|
73
|
+
run_resources(project_dir, status=args.status, service=args.service, json_output=args.json_output, no_cloud=args.no_cloud, credential_expiry=credential_expiry)
|
|
74
|
+
except KeyboardInterrupt:
|
|
75
|
+
print()
|
|
76
|
+
|
|
77
|
+
print_update_notice(version_thread)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if __name__ == "__main__":
|
|
81
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Shared rich console for CLI commands."""
|
|
2
|
+
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
from rich.theme import Theme
|
|
5
|
+
|
|
6
|
+
theme = Theme({
|
|
7
|
+
"info": "cyan",
|
|
8
|
+
"success": "green",
|
|
9
|
+
"warning": "yellow",
|
|
10
|
+
"error": "red bold",
|
|
11
|
+
"muted": "dim",
|
|
12
|
+
"cost.high": "red bold",
|
|
13
|
+
"cost.medium": "yellow",
|
|
14
|
+
"cost.low": "green",
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
console = Console(theme=theme)
|