Skip to content

Commit f95861c

Browse files
committed
Add TUI mode
1 parent c2072fe commit f95861c

9 files changed

Lines changed: 1112 additions & 27 deletions

File tree

README.md

Lines changed: 67 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
A standalone Go binary that analyzes StackRox Sensor Prometheus metrics using declarative TOML rule files.
44

5-
## Features
5+
## Features
66

7-
- **Load-Aware Analysis**: Automatically detects cluster load level (low/medium/high) and adjusts thresholds accordingly
8-
- **Correlation Rules**: Rules can reference other metrics for intelligent status evaluation
9-
- **ACS Versioning**: Rules specify supported ACS versions and are filtered automatically
10-
- **Template-Based Reports**: Markdown reports generated from templates
11-
- **Console Output**: Default colorful console output with tables
7+
- **🎮 Interactive TUI**: Beautiful terminal UI with keyboard navigation (powered by [Bubble Tea](https://github.com/charmbracelet/bubbletea))
8+
- **📊 Load-Aware Analysis**: Automatically detects cluster load level (low/medium/high) and adjusts thresholds accordingly
9+
- **🔗 Correlation Rules**: Rules can reference other metrics for intelligent status evaluation
10+
- **🏷️ ACS Versioning**: Rules specify supported ACS versions and are filtered automatically
11+
- **📝 Template-Based Reports**: Markdown reports generated from templates
12+
- **🖥️ Console Output**: Default colorful console output with tables
1213

1314
## Installation
1415

@@ -18,8 +19,24 @@ make build
1819

1920
## Usage
2021

22+
### Interactive TUI Mode (Recommended)
23+
24+
```bash
25+
# Launch interactive terminal UI
26+
./bin/metrics-analyzer analyze metrics.txt --format tui
27+
```
28+
29+
**TUI Features:**
30+
- Navigate results with ``/`` or `j`/`k` keys
31+
- Press `Enter` to view detailed information
32+
- Filter by status with `1-4` keys (All/Red/Yellow/Green)
33+
- Search with `/` key
34+
- Press `?` for help
35+
36+
### Console & Markdown Output
37+
2138
```bash
22-
# Analyze metrics (console output)
39+
# Analyze metrics (console output - default)
2340
./bin/metrics-analyzer analyze metrics.txt
2441

2542
# Analyze with custom rules directory
@@ -33,7 +50,11 @@ make build
3350

3451
# Specify ACS version
3552
./bin/metrics-analyzer analyze metrics.txt --acs-version 4.8
53+
```
54+
55+
### Utility Commands
3656

57+
```bash
3758
# Validate rules (defaults to current directory)
3859
./bin/metrics-analyzer validate
3960

@@ -44,16 +65,36 @@ make build
4465
./bin/metrics-analyzer list-rules
4566
```
4667

68+
## TUI Keyboard Shortcuts
69+
70+
| Key | Action |
71+
|-----|--------|
72+
| ``/`k`, ``/`j` | Navigate up/down |
73+
| `Enter`/`` | View details |
74+
| ``/`Esc` | Go back |
75+
| `g`/`Home` | Go to top |
76+
| `G`/`End` | Go to bottom |
77+
| `PgUp`/`PgDn` | Page up/down |
78+
| `/` | Search/filter |
79+
| `1-4` | Filter by status (All/Red/Yellow/Green) |
80+
| `?` | Toggle help |
81+
| `q` | Quit |
82+
4783
## Project Structure
4884

49-
- `cmd/metrics-analyzer/` - CLI entry point
50-
- `internal/parser/` - Prometheus metrics parser
51-
- `internal/rules/` - TOML rule loader and validator
52-
- `internal/loadlevel/` - Load level detection engine
53-
- `internal/evaluator/` - Rule evaluation logic
54-
- `internal/reporter/` - Report generation (markdown/console)
55-
- `automated-rules/` - TOML rule definitions
56-
- `templates/` - Report templates
85+
```
86+
sensor-metrics-analyzer-go/
87+
├── cmd/metrics-analyzer/ # CLI entry point
88+
├── internal/
89+
│ ├── parser/ # Prometheus metrics parser
90+
│ ├── rules/ # TOML rule loader and validator
91+
│ ├── loadlevel/ # Load level detection engine
92+
│ ├── evaluator/ # Rule evaluation logic
93+
│ ├── reporter/ # Report generation (markdown/console)
94+
│ └── tui/ # Interactive terminal UI (Bubble Tea)
95+
├── automated-rules/ # TOML rule definitions
96+
└── templates/ # Report templates
97+
```
5798

5899
## Testing
59100

@@ -67,3 +108,14 @@ python3 analyze_metrics_full.py metrics.txt > /tmp/python-output.txt
67108
go run testdata/compare_outputs.go /tmp/python-output.txt /tmp/go-report.md
68109
```
69110

111+
## Dependencies
112+
113+
Built with:
114+
- [Bubble Tea](https://github.com/charmbracelet/bubbletea) - TUI framework
115+
- [Lip Gloss](https://github.com/charmbracelet/lipgloss) - Style definitions
116+
- [Bubbles](https://github.com/charmbracelet/bubbles) - TUI components
117+
- [go-pretty](https://github.com/jedib0t/go-pretty) - Table formatting
118+
119+
## License
120+
121+
Apache 2.0 - See [LICENSE](LICENSE) for details.

cmd/metrics-analyzer/main.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/stackrox/sensor-metrics-analyzer/internal/parser"
1313
"github.com/stackrox/sensor-metrics-analyzer/internal/reporter"
1414
"github.com/stackrox/sensor-metrics-analyzer/internal/rules"
15+
"github.com/stackrox/sensor-metrics-analyzer/internal/tui"
1516
)
1617

1718
func main() {
@@ -41,35 +42,51 @@ func analyzeCommand() {
4142
rulesDir := fs.String("rules", ".", "Directory containing TOML rules (default: current directory)")
4243
loadLevelDir := fs.String("load-level-dir", "./load-level", "Directory containing load detection rules")
4344
output := fs.String("output", "", "Output file (default: stdout)")
44-
format := fs.String("format", "console", "Output format: console, markdown")
45+
format := fs.String("format", "console", "Output format: console, markdown, tui (interactive)")
4546
clusterName := fs.String("cluster", "", "Cluster name (extracted from filename if not provided)")
4647
loadLevelOverride := fs.String("load-level", "", "Override detected load level (low/medium/high)")
4748
acsVersionOverride := fs.String("acs-version", "", "Override detected ACS version")
4849
templatePath := fs.String("template", "./templates/markdown.tmpl", "Path to markdown template")
4950

5051
fs.Usage = func() {
51-
fmt.Fprintf(os.Stderr, "Usage: metrics-analyzer analyze <metrics-file> [flags]\n\n")
52+
fmt.Fprintf(os.Stderr, "Usage: metrics-analyzer analyze [flags] <metrics-file>\n\n")
5253
fmt.Fprintf(os.Stderr, "Analyzes Prometheus metrics using declarative TOML rules.\n\n")
5354
fmt.Fprintf(os.Stderr, "Arguments:\n")
5455
fmt.Fprintf(os.Stderr, " metrics-file Path to Prometheus metrics file\n\n")
5556
fmt.Fprintf(os.Stderr, "Flags:\n")
5657
fs.PrintDefaults()
58+
fmt.Fprintf(os.Stderr, "\n⚠️ Note: Flags must come BEFORE the metrics file!\n")
5759
fmt.Fprintf(os.Stderr, "\nExamples:\n")
5860
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze metrics.txt\n")
59-
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze metrics.txt --rules ./automated-rules\n")
60-
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze metrics.txt --format markdown --output report.md\n")
61-
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze metrics.txt --load-level high --acs-version 4.8\n")
61+
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze --rules ./automated-rules metrics.txt\n")
62+
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze --format markdown --output report.md metrics.txt\n")
63+
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze --format tui --rules ./automated-rules metrics.txt\n")
6264
}
6365

6466
fs.Parse(os.Args[2:])
6567

6668
if fs.NArg() < 1 {
67-
fmt.Fprintf(os.Stderr, "Usage: metrics-analyzer analyze <metrics-file> [flags]\n")
69+
fmt.Fprintf(os.Stderr, "Error: missing metrics file\n")
70+
fmt.Fprintf(os.Stderr, "Usage: metrics-analyzer analyze [flags] <metrics-file>\n")
6871
os.Exit(1)
6972
}
7073

7174
metricsFile := fs.Arg(0)
7275

76+
// Check for flags after positional argument (common mistake)
77+
for i := 1; i < fs.NArg(); i++ {
78+
arg := fs.Arg(i)
79+
if strings.HasPrefix(arg, "-") {
80+
fmt.Fprintf(os.Stderr, "Error: flags must come before the metrics file, not after\n")
81+
fmt.Fprintf(os.Stderr, " Found flag '%s' after '%s'\n\n", arg, metricsFile)
82+
fmt.Fprintf(os.Stderr, "Correct usage:\n")
83+
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze [flags] <metrics-file>\n\n")
84+
fmt.Fprintf(os.Stderr, "Example:\n")
85+
fmt.Fprintf(os.Stderr, " metrics-analyzer analyze --format tui --rules ./automated-rules %s\n", metricsFile)
86+
os.Exit(1)
87+
}
88+
}
89+
7390
// Extract cluster name from filename if not provided
7491
if *clusterName == "" {
7592
*clusterName = extractClusterName(metricsFile)
@@ -129,6 +146,16 @@ func analyzeCommand() {
129146
// Generate report
130147
var outputContent string
131148
switch *format {
149+
case "tui":
150+
// Interactive TUI mode
151+
if *output != "" {
152+
fmt.Fprintf(os.Stderr, "Warning: --output is ignored in TUI mode\n")
153+
}
154+
if err := tui.Run(report); err != nil {
155+
fmt.Fprintf(os.Stderr, "TUI error: %v\n", err)
156+
os.Exit(1)
157+
}
158+
return
132159
case "console":
133160
// If output file specified, still use console format
134161
if *output != "" {
@@ -247,10 +274,13 @@ func printUsage() {
247274
fmt.Println()
248275
fmt.Println("Examples:")
249276
fmt.Println(" metrics-analyzer analyze metrics.txt")
250-
fmt.Println(" metrics-analyzer analyze metrics.txt --rules ./automated-rules")
251-
fmt.Println(" metrics-analyzer analyze metrics.txt --format markdown --output report.md")
252-
fmt.Println(" metrics-analyzer analyze metrics.txt --load-level high --acs-version 4.8")
277+
fmt.Println(" metrics-analyzer analyze --rules ./automated-rules metrics.txt")
278+
fmt.Println(" metrics-analyzer analyze --format markdown --output report.md metrics.txt")
279+
fmt.Println(" metrics-analyzer analyze --format tui --rules ./automated-rules metrics.txt")
280+
fmt.Println(" metrics-analyzer analyze --load-level high --acs-version 4.8 metrics.txt")
253281
fmt.Println(" metrics-analyzer validate")
254282
fmt.Println(" metrics-analyzer validate ./automated-rules")
255283
fmt.Println(" metrics-analyzer list-rules")
284+
fmt.Println()
285+
fmt.Println("Note: Flags must come BEFORE positional arguments!")
256286
}

go.mod

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,32 @@ go 1.24.9
44

55
require (
66
github.com/BurntSushi/toml v1.5.0
7+
github.com/charmbracelet/bubbles v0.21.0
8+
github.com/charmbracelet/bubbletea v1.3.10
9+
github.com/charmbracelet/lipgloss v1.1.0
710
github.com/fatih/color v1.18.0
811
github.com/jedib0t/go-pretty/v6 v6.7.1
12+
golang.org/x/term v0.29.0
913
)
1014

1115
require (
16+
github.com/atotto/clipboard v0.1.4 // indirect
17+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
18+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
19+
github.com/charmbracelet/x/ansi v0.10.1 // indirect
20+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
21+
github.com/charmbracelet/x/term v0.2.1 // indirect
22+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
23+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
1224
github.com/mattn/go-colorable v0.1.13 // indirect
1325
github.com/mattn/go-isatty v0.0.20 // indirect
26+
github.com/mattn/go-localereader v0.0.1 // indirect
1427
github.com/mattn/go-runewidth v0.0.16 // indirect
28+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
29+
github.com/muesli/cancelreader v0.2.2 // indirect
30+
github.com/muesli/termenv v0.16.0 // indirect
1531
github.com/rivo/uniseg v0.4.7 // indirect
16-
golang.org/x/sys v0.30.0 // indirect
32+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
33+
golang.org/x/sys v0.36.0 // indirect
1734
golang.org/x/text v0.22.0 // indirect
1835
)

go.sum

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,66 @@
11
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
22
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
3+
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
4+
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
5+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
6+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
7+
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
8+
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
9+
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
10+
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
11+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
12+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
13+
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
14+
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
15+
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
16+
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
17+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
18+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
19+
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
20+
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
321
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
422
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
23+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
24+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
525
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
626
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
727
github.com/jedib0t/go-pretty/v6 v6.7.1 h1:bHDSsj93NuJ563hHuM7ohk/wpX7BmRFNIsVv1ssI2/M=
828
github.com/jedib0t/go-pretty/v6 v6.7.1/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
29+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
30+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
931
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
1032
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
1133
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
1234
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
1335
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
36+
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
37+
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
1438
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
1539
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
40+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
41+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
42+
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
43+
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
44+
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
45+
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
1646
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1747
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1848
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
1949
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
2050
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
2151
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
2252
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
53+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
54+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
55+
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
56+
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
57+
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2358
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2459
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
25-
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
26-
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
60+
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
61+
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
62+
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
63+
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
2764
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
2865
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
2966
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

0 commit comments

Comments
 (0)