Commit 4c2d084
Feat/cli improvements (#5)
* feat: add structured output, shell completion, ssh, describe, and wait
Add five CLI improvements to close the gap with modern cloud CLIs:
1. `--output json|yaml|table` global flag (-o) for structured output
across all list and describe commands, enabling scripting and
automation pipelines (e.g. `verda vm list -o json | jq`).
2. `verda completion` command for bash, zsh, fish, and powershell
shell completions using Cobra's built-in generation.
3. `verda ssh <instance>` command to SSH into a running VM by
hostname or ID. Resolves IP from the API and exec's into ssh.
Supports --user, --key, and pass-through args via --.
4. `verda vm describe` and `verda volume describe` commands to
show detailed info about a single resource (aliased as get/show),
with full --output flag support.
5. `--wait` and `--wait-timeout` flags on vm create, vm action,
volume create, and volume action. Generic polling utility with
animated spinner for interactive use and silent mode for
structured output.
Includes 33 new unit tests covering all features.
* docs: update README with new commands and global flags
Add documentation for ssh, describe, completion commands,
--output flag, structured output examples, and --wait flag.
* feat: add images, availability, and cost commands
Add three new command groups:
- `verda images` — browse OS images with --type and --category
filters. Shows name, category, and details (e.g., CUDA version).
- `verda availability` — check instance type availability per
location. Supports --location, --type, and --spot flags.
Single-type check returns a boolean; full matrix shows all
available types per datacenter.
- `verda cost` — cost estimation, pricing, and billing:
- `estimate` — calculate hourly/daily/monthly costs for an
instance type + optional volumes, with spot pricing support
- `price-history` — show historical fixed and dynamic pricing
- `balance` — display current account balance
All commands support --output json/yaml for scripting.
Includes tests for cost math, formatting, and filtering logic.
* fix(cost): use list-all endpoint instead of single-type lookup
The /instance-types/{type} endpoint returns 404. Fetch all instance
types and filter client-side instead.
* fix(cost): use lowercase currency to match API expectations
The Verda API requires lowercase 'usd', not 'USD'.
* fix(cost): remove price-history subcommand
The /instance-types/price-history endpoint has been removed by the
API (410 Gone). Dynamic pricing is no longer supported.
* feat: add verda locations command
List available datacenter locations with code, name, and country.
Supports --output json/yaml.
* test+docs: add locations tests and update README
* feat(cost): add running subcommand and live test script
- `verda cost running` shows burn rate of all running instances
with per-instance breakdown including attached volume costs
- Add scripts/live-test.sh for automated integration testing
* test+docs: add running cost tests and update README
* fix: suppress spinners for structured output
When --output is json or yaml, return nil from Factory.Status()
so spinners don't write escape codes to stdout and break piping.
* feat: add instance-types command and non-interactive vm list
- `verda instance-types` lists all types with specs and pricing,
with --gpu, --cpu, and --spot filters. Groups output by GPU vs CPU.
- `verda vm list` now prints a static table when stdout is piped
or redirected, instead of launching the interactive picker.
Interactive mode still works in a terminal.
* fix(instance-types): clean GPU descriptions and improve formatting
- Strip duplicate count prefix from API GPU descriptions
(e.g., "1x 1x H100 SXM5 80GB" → "1x H100 SXM5")
- Strip trailing VRAM from description (shown in separate column)
- Format large RAM values as TB (e.g., 1440GB → 1.4TB)
- Widen GPU column for longer names
* fix(vm list): dynamic hostname column width in table mode
Compute max hostname length so columns stay aligned with long names.
* docs: add instance-types to README
* refactor: move renderVolumeSummary to dedicated view.go
* refactor: extract UniqueVolumeIDs to shared util
* feat: code review fixes, interactive pickers, and test infrastructure
- Separate "Flags" from "Global Flags" in help output
- Register --output flag completion values (json/yaml/table)
- Remove dead JSON bool field from vm list options
- Fix Poll() timeout to return error instead of nil
- Consolidate duplicate polling code from status_view.go into shared wait.go
- Centralize status messages and terminal statuses in status_messages.go
- Add interactive picker for verda ssh (no-arg shows running instances)
- Add interactive picker for vm describe and volume describe (no-arg shows list)
- Add reusable TestFactory in cmd/util/testing.go for command-level tests
- Add arg-validation and status message tests
- Fix pre-existing lint issues (stuttering type names, hugeParam, goimports)
- Ignore .ai/notes/ and docs/plans/ in .gitignore
* fix: version output and instance card display issues
- Version: show human-readable text by default, JSON only with -o json
- Image: show image slug instead of volume name, append OS name if different
- Compute: strip duplicate "1x" prefix from GPU description
- Pricing: remove redundant field (only fixed pricing exists)
- Storage Status: show actual status (attached/detached) with "(OS)" label
* fix(version): show only version and platform by default
Full build details still available via verda version -o json.
* feat(vm): add availability command showing instance specs and pricing
Joins instance type specs, pricing, and live availability data into a
single view — sorted by price, filterable by location, type, kind, and
spot. Addresses user request for a native alternative to the Python
availability script.
Usage:
verda vm availability
verda vm availability --location FIN-01 --kind gpu --spot
verda vm availability -o json
* fix: resolve gosec G204 and G602 lint warnings
- ssh.go: suppress G204 for intentional syscall.Exec into ssh
- images_test.go, instancetypes_test.go: use empty slice instead of nil
to avoid G602 false positive on nil range
---------
Co-authored-by: Milosz Szewczak <milosz@datacrunch.io>1 parent c0b869a commit 4c2d084
56 files changed
Lines changed: 4242 additions & 191 deletions
File tree
- internal/verda-cli
- cmd
- availability
- completion
- cost
- images
- instancetypes
- locations
- sshkey
- ssh
- startupscript
- util
- version
- vm
- volume
- options
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
360 | 361 | | |
361 | 362 | | |
362 | 363 | | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
110 | 110 | | |
111 | 111 | | |
112 | 112 | | |
| 113 | + | |
113 | 114 | | |
114 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
115 | 120 | | |
116 | 121 | | |
117 | 122 | | |
118 | 123 | | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
119 | 127 | | |
| 128 | + | |
120 | 129 | | |
121 | 130 | | |
122 | 131 | | |
| |||
125 | 134 | | |
126 | 135 | | |
127 | 136 | | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
133 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
134 | 157 | | |
135 | 158 | | |
136 | 159 | | |
137 | 160 | | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
144 | 171 | | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
145 | 207 | | |
146 | 208 | | |
147 | 209 | | |
| |||
183 | 245 | | |
184 | 246 | | |
185 | 247 | | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
186 | 261 | | |
187 | 262 | | |
188 | 263 | | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
195 | 296 | | |
196 | 297 | | |
197 | 298 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
17 | 20 | | |
18 | 21 | | |
19 | 22 | | |
| |||
23 | 26 | | |
24 | 27 | | |
25 | 28 | | |
26 | | - | |
27 | 29 | | |
28 | 30 | | |
29 | 31 | | |
| |||
0 commit comments