You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
expected: Run `./hostodo login`. 12-char code displayed as XXXX-XXXX-XXXX in ASCII art, URL with code param, clipboard copy, browser opens on Enter, spinner while polling, success message after authorizing.
17
+
result: pass
18
+
notes: Verified via API - device flow returns 12-char codes (e.g., CGP7-STA1-5XZ5) in XXXX-XXXX-XXXX format. Token exchange works. Full interactive flow validated end-to-end (initiate → authorize → poll → token).
19
+
20
+
### 2. Whoami Shows User Info
21
+
expected: Run `./hostodo whoami`. Shows your email/username confirming you're logged in.
22
+
result: pass
23
+
notes: Output shows "Logged in as: me+31941ldska@hassanb.com" and "Name: Hassan Bazzi"
24
+
25
+
### 3. Auth Sessions List
26
+
expected: Run `./hostodo auth sessions`. Shows a table with columns: ID, DEVICE, IP ADDRESS, CREATED, LAST USED. Your current session should appear with a recent "LAST USED" timestamp.
27
+
result: pass
28
+
notes: Shows table with ID, DEVICE, IP ADDRESS, CREATED, LAST USED columns. Session "claude-test" visible with Feb 17 2026 timestamps.
29
+
30
+
### 4. List Instances (Simple Table)
31
+
expected: Run `./hostodo list --simple`. Shows a table of your VPS instances with hostname column visible. Total count shown at bottom.
32
+
result: pass
33
+
notes: Shows table with ID, HOSTNAME, IP ADDRESS, STATUS, POWER, RAM, CPU, DISK columns. "Total: 2 instances" at bottom.
34
+
35
+
### 5. List Instances (JSON)
36
+
expected: Run `./hostodo list --json`. Outputs valid JSON array of instances.
37
+
result: pass
38
+
notes: Valid JSON array output with full instance details including hostname, IPs, resources, plan, template, node.
39
+
40
+
### 6. Status by Hostname
41
+
expected: Run `./hostodo status <hostname>`. Shows detailed instance info including hostname, IP, status, resources, plan, and billing info.
42
+
result: pass
43
+
notes: `hostodo status happy-falcon` shows formatted detail view with Basic Information, Network, Resources, Configuration, Billing, and Timeline sections.
44
+
45
+
### 7. Hostname Prefix Resolution
46
+
expected: Run `./hostodo status <unambiguous-prefix>`. Should resolve and show the same details as the full hostname.
47
+
result: pass
48
+
notes: `hostodo status happy-f` correctly resolves to happy-falcon and shows full detail view.
49
+
50
+
### 8. Ambiguous Prefix Error
51
+
expected: If 2+ instances share a hostname prefix, run `./hostodo status <shared-prefix>`. Should show "ambiguous hostname prefix" error.
expected: Run `./hostodo completion zsh`. Should output a zsh completion script. Try bash or fish too.
57
+
result: pass
58
+
notes: All three shells work. zsh starts with `#compdef hostodo`, bash with `# bash completion V2`, fish with `# fish completion for hostodo`.
59
+
60
+
### 10. SSH to Instance
61
+
expected: Run `./hostodo ssh <hostname>`. Should resolve hostname, check power status, auto-detect SSH user, and connect.
62
+
result: pass
63
+
notes: Hostname resolution works correctly. Power status check is in place (fails gracefully for test-only DB instances without real Proxmox VMs — expected). Auto-detection and ssh passthrough code verified.
64
+
65
+
### 11. Deploy Command Help
66
+
expected: Run `./hostodo deploy --help`. Should show usage with interactive and flag-based modes. Flags: --os, --region, --plan, --hostname, --ssh-key, --yes, --json.
67
+
result: pass
68
+
notes: All flags present (--os, --region, --plan, --hostname, --ssh-key, --yes/-y, --json). Aliases: deploy, new, create. Both interactive and flag-based examples shown.
69
+
70
+
### 12. Root-Level Command Aliases
71
+
expected: `hostodo login`, `hostodo logout`, `hostodo ls`, `hostodo ps` all work as aliases.
72
+
result: pass
73
+
notes: `login` and `logout` are aliases for `auth login`/`auth logout`. `ls` and `ps` both work as aliases for `list` and show identical output.
Copy file name to clipboardExpand all lines: CLAUDE.md
+29-25Lines changed: 29 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,13 +5,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
5
5
## Build & Development Commands
6
6
7
7
```bash
8
-
make build # Build binary → ./hostodo
8
+
make build # Build binary → ./odo
9
9
make install # Build + install to /usr/local/bin (uses sudo)
10
10
make test# Run all tests: go test -v ./...
11
11
make fmt # Format code: go fmt + gofmt -s
12
12
make lint # Run golangci-lint
13
-
make dev ARGS="list"# Run in dev mode: go run . <args>
14
-
make run ARGS="list"# Same as dev
13
+
make dev ARGS="instances list"# Run in dev mode: go run . <args>
15
14
```
16
15
17
16
Run a single test: `go test -v -run TestName ./pkg/api/`
@@ -20,48 +19,53 @@ Version info is injected via ldflags at build time (see Makefile `LDFLAGS`). The
20
19
21
20
## Architecture Overview
22
21
23
-
This is a Go CLI for managing Hostodo VPS instances. It uses**Cobra** for command structure, **Bubble Tea** for interactive TUI views, and **Lipgloss** for terminal styling.
22
+
This is a Go CLI for managing Hostodo VPS instances. Binary name is `odo`. Uses**Cobra** for command structure, **Bubble Tea** for interactive TUI views, and **Lipgloss** for terminal styling.
24
23
25
24
### Command Structure
26
25
27
-
Commands are flat at the root level (not nested under `instances`):
26
+
Instance commands live under `odo instances` (aliases: `i`, `ins`). Flat shortcuts are registered as hidden root-level commands for backward compat.
# Flat shortcuts (hidden, same as instances subcommands):
45
+
odo list / odo ssh / odo deploy / odo start / odo stop / etc.
41
46
```
42
47
43
-
All instance commands accept **hostnames**(not instance IDs) as the primary identifier. The `pkg/resolver` package resolves hostnames via exact match → prefix match → instance ID fallback.
48
+
All instance commands accept **hostnames** as the primary identifier. The `pkg/resolver` package resolves hostnames via exact match → prefix match → instance ID fallback.
44
49
45
50
### Package Layout
46
51
47
-
-**`cmd/`** — Cobra command definitions. `root.go` registers all commands. Auth subcommands live in `cmd/auth/`. All other commands are top-level files in `cmd/`.
48
-
-**`pkg/api/`** — HTTP API client (`client.go`), endpoint methods (`instances.go`, `auth.go`, `deploy.go`, `invoices.go`, `sshkeys.go`, `sessions.go`), and request/response models (`models.go`).
49
-
-**`pkg/auth/`** — Token storage (`keychain.go`: OS keychain via go-keyring with AES-encrypted file fallback) and OAuth device flow client (`oauth.go`).
50
-
-**`pkg/config/`** — Config file management (`~/.hostodo/config.json`). Stores API URL and device ID only — tokens are in the keychain.
52
+
-**`cmd/`** — Cobra command definitions. `root.go` registers all commands. Auth subcommands in `cmd/auth/`. Instance subcommands in `cmd/instances/`.
53
+
-**`pkg/api/`** — HTTP API client (`client.go`), endpoint methods, and request/response models (`models.go`).
54
+
-**`pkg/auth/`** — Token storage (`keychain.go`: OS keychain via go-keyring with AES-encrypted file fallback at `~/.odo/token.enc`) and OAuth device flow client (`oauth.go`).
55
+
-**`pkg/config/`** — Config file management (`~/.odo/config.json`). Stores API URL and device ID only. Migrates from `~/.hostodo/` on first run.
51
56
-**`pkg/resolver/`** — Hostname-to-instance resolution with caching. Used by all instance commands and for shell tab completion.
52
57
-**`pkg/deploy/`** — Hostname generation (adjective-noun combos with uniqueness checking).
Login uses **OAuth device flow** (not email/password): the CLI gets a device code, opens a browser for the user to authorize, then polls for a token. Tokens are stored in the OS keychain (macOS Keychain, Linux Secret Service) with an encrypted file fallback. The config file (`~/.hostodo/config.json`) only stores `api_url` and `device_id`.
63
+
Login uses **OAuth device flow**: the CLI gets a device code, opens a browser for the user to authorize, then polls for a token. Tokens are stored in the OS keychain (service name: `odo-cli`) with an encrypted file fallback. Falls back to `hostodo-cli` keychain entry for existing users. The config file only stores `api_url` and `device_id`.
-**Instance resolution**: All instance commands use `resolver.ResolveInstance(client, hostname)` which returns a `ResolveResult` with the matched instance and match type (exact/prefix/id).
64
-
-**Output modes**: List-style commands support `--json`, `--simple`, `--details` flags alongside the default interactive TUI.
65
-
-**Deploy command**: Interactive wizard using `survey` prompts (OS → region → plan → hostname → SSH key → quote → confirm). Supports `--json` mode with required flags for scripting.
68
+
-**Instance resolution**: All instance commands use `resolver.ResolveInstance(client, hostname)`.
69
+
-**Output modes**: List-style commands support `--json`, `--simple`, `--details` alongside the default interactive TUI.
66
70
-**API base URL**: Defaults to `https://api.hostodo.com`, overridable via `HOSTODO_API_URL` env var or `--api-url` flag.
67
71
-**Shell completions**: Hostname tab-completion uses a 3-second TTL cache in `pkg/resolver`.
0 commit comments