Context
5-agent parallel QA audit of PR #13 found 65 issues. This issue covers the 14 HIGH-priority items that require Bhautik's context on the interactive UX patterns, plus README/docs fixes.
These should be fixed before public launch (but don't block merging PR #13 — the CRITICALs in #14 block merge).
Part 1: Non-Interactive Guards (8 issues)
Every command using pterm.DefaultInteractiveSelect or pterm.DefaultInteractiveConfirm will crash or hang in CI/pipes/non-TTY environments. Each needs:
- A
terminal.IsInteractive() check before the interactive call
- A
--force flag (for destructive commands) or a clear error message telling users to pass flags
H4: domains delete — no --force flag
File: cmd/domains/domains_delete.go:32
Fix: Add --force flag. If !terminal.IsInteractive() && !c.Bool("force") → return error: "non-interactive mode: use --force to confirm deletion"
H5: domains add — pickEnvironment crashes in non-TTY
File: cmd/domains/helpers.go:85
Fix: If !terminal.IsInteractive() and --environment not set → return error: "non-interactive mode: use --environment flag"
H6: domains verify — pickDomain crashes in non-TTY
File: cmd/domains/helpers.go:32
Fix: If !terminal.IsInteractive() and no domain arg/flag → return error: "non-interactive mode: use --domain flag"
H7: open — multi-env/deployment selector crashes in non-TTY
File: cmd/open/open.go:96-129
Fix: If !terminal.IsInteractive() and multiple envs/deployments → use the first one (or error with suggestion to pass --project)
H8: init — project/env selector crashes in non-TTY
File: cmd/init/init.go:41-114
Fix: If !terminal.IsInteractive() and --project not set → return error: "non-interactive mode: use --project flag"
H9: deployments cancel — no --force flag
File: cmd/deployments/deployments_delete.go:31
Fix: Same pattern as H4 — add --force flag with non-interactive guard.
H10: deployments zero-args — pickDeployment crashes in non-TTY
File: cmd/deployments/helpers.go:20
Fix: If !terminal.IsInteractive() and no args → return error suggesting positional args or --deployment flag.
H-extra: environments delete — no --force flag (found by UX audit)
File: cmd/environments/environments_delete.go:32-42
Fix: Same pattern — add --force flag. NOTE: The README CI examples already reference --force on this command but the flag doesn't exist yet.
Part 2: Logic Fallthroughs (2 issues)
H11: env/helpers.go select-loop fallthrough
File: cmd/env/helpers.go:60-65
Problem: If the interactive select loop completes without matching (shouldn't happen normally), the function falls through with empty envID → API call with empty ID → confusing 404.
Fix: Add return "", nil, fmt.Errorf("no environment selected") after the select loop.
H12: scale.go same fallthrough
File: cmd/scale/scale.go:92-97
Problem: Same pattern — select loop fallthrough leaves envID empty.
Fix: Add return "", "", fmt.Errorf("no environment selected") after the select loop.
Part 3: README & Documentation (4 issues)
R1: Three broken CI examples in README
File: README.md — "Non-interactive / CI usage" section
Problem: These examples reference flags that don't exist on the commands:
createos projects get --project <id> → projects get has no --project flag
createos deployments logs --project <id> --deployment <id> → no such flags
createos deployments retrigger --project <id> --deployment <id> → no such flags
Fix (choose one):
- A) Add
--project and --deployment flags to these commands (preferred — matches other command groups)
- B) Change README examples to use positional args:
createos projects get <id>
R2: Cronjobs section missing from README
Problem: 8 cronjob subcommands (list, get, create, update, delete, suspend, unsuspend, activities) are completely undocumented in the README.
Fix: Add a "Cron Jobs" section to README with all subcommands + CI examples.
R3: oauth-clients delete missing from README
Problem: The OAuth Clients table lists list, create, instructions but not delete.
Fix: Add createos oauth-clients delete | Delete an OAuth client row.
R4: Home screen me out of alphabetical order
File: cmd/root/root.go:138-139
Problem: me appears after templates. Should be between logout and oauth-clients.
Fix: Move the line.
Part 4: Cronjob-specific fixes (3 issues)
M11: --method GET explicit still triggers interactive prompt
File: cmd/cronjobs/cronjobs_create.go:127
Problem: Condition is if method == "GET" but GET is the default. If user explicitly passes --method GET, the prompt still shows.
Fix: Change to if !c.IsSet("method")
M12: cronjobs update silently ignores JSON unmarshal error
File: cmd/cronjobs/cronjobs_update.go:57
Problem: _ = json.Unmarshal(*existing.Settings, ¤tSettings) — if settings JSON is malformed, zero values silently overwrite.
Fix: Check the error: if err := json.Unmarshal(...); err != nil { return fmt.Errorf("could not parse existing settings: %w", err) }
M-extra: cronjobs update — defaultMethod unused in interactive select
File: cmd/cronjobs/cronjobs_update.go:112
Problem: _ = defaultMethod — the current method is computed but not used as the default selection.
Fix: Use pterm.DefaultInteractiveSelect.WithDefaultOption(defaultMethod)
Acceptance Criteria
Context
5-agent parallel QA audit of PR #13 found 65 issues. This issue covers the 14 HIGH-priority items that require Bhautik's context on the interactive UX patterns, plus README/docs fixes.
These should be fixed before public launch (but don't block merging PR #13 — the CRITICALs in #14 block merge).
Part 1: Non-Interactive Guards (8 issues)
Every command using
pterm.DefaultInteractiveSelectorpterm.DefaultInteractiveConfirmwill crash or hang in CI/pipes/non-TTY environments. Each needs:terminal.IsInteractive()check before the interactive call--forceflag (for destructive commands) or a clear error message telling users to pass flagsH4:
domains delete— no--forceflagFile:
cmd/domains/domains_delete.go:32Fix: Add
--forceflag. If!terminal.IsInteractive() && !c.Bool("force")→ return error:"non-interactive mode: use --force to confirm deletion"H5:
domains add—pickEnvironmentcrashes in non-TTYFile:
cmd/domains/helpers.go:85Fix: If
!terminal.IsInteractive()and--environmentnot set → return error:"non-interactive mode: use --environment flag"H6:
domains verify—pickDomaincrashes in non-TTYFile:
cmd/domains/helpers.go:32Fix: If
!terminal.IsInteractive()and no domain arg/flag → return error:"non-interactive mode: use --domain flag"H7:
open— multi-env/deployment selector crashes in non-TTYFile:
cmd/open/open.go:96-129Fix: If
!terminal.IsInteractive()and multiple envs/deployments → use the first one (or error with suggestion to pass--project)H8:
init— project/env selector crashes in non-TTYFile:
cmd/init/init.go:41-114Fix: If
!terminal.IsInteractive()and--projectnot set → return error:"non-interactive mode: use --project flag"H9:
deployments cancel— no--forceflagFile:
cmd/deployments/deployments_delete.go:31Fix: Same pattern as H4 — add
--forceflag with non-interactive guard.H10:
deploymentszero-args —pickDeploymentcrashes in non-TTYFile:
cmd/deployments/helpers.go:20Fix: If
!terminal.IsInteractive()and no args → return error suggesting positional args or--deploymentflag.H-extra:
environments delete— no--forceflag (found by UX audit)File:
cmd/environments/environments_delete.go:32-42Fix: Same pattern — add
--forceflag. NOTE: The README CI examples already reference--forceon this command but the flag doesn't exist yet.Part 2: Logic Fallthroughs (2 issues)
H11:
env/helpers.goselect-loop fallthroughFile:
cmd/env/helpers.go:60-65Problem: If the interactive select loop completes without matching (shouldn't happen normally), the function falls through with empty envID → API call with empty ID → confusing 404.
Fix: Add
return "", nil, fmt.Errorf("no environment selected")after the select loop.H12:
scale.gosame fallthroughFile:
cmd/scale/scale.go:92-97Problem: Same pattern — select loop fallthrough leaves envID empty.
Fix: Add
return "", "", fmt.Errorf("no environment selected")after the select loop.Part 3: README & Documentation (4 issues)
R1: Three broken CI examples in README
File:
README.md— "Non-interactive / CI usage" sectionProblem: These examples reference flags that don't exist on the commands:
createos projects get --project <id>→projects gethas no--projectflagcreateos deployments logs --project <id> --deployment <id>→ no such flagscreateos deployments retrigger --project <id> --deployment <id>→ no such flagsFix (choose one):
--projectand--deploymentflags to these commands (preferred — matches other command groups)createos projects get <id>R2: Cronjobs section missing from README
Problem: 8 cronjob subcommands (list, get, create, update, delete, suspend, unsuspend, activities) are completely undocumented in the README.
Fix: Add a "Cron Jobs" section to README with all subcommands + CI examples.
R3:
oauth-clients deletemissing from READMEProblem: The OAuth Clients table lists
list,create,instructionsbut notdelete.Fix: Add
createos oauth-clients delete | Delete an OAuth clientrow.R4: Home screen
meout of alphabetical orderFile:
cmd/root/root.go:138-139Problem:
meappears aftertemplates. Should be betweenlogoutandoauth-clients.Fix: Move the line.
Part 4: Cronjob-specific fixes (3 issues)
M11:
--method GETexplicit still triggers interactive promptFile:
cmd/cronjobs/cronjobs_create.go:127Problem: Condition is
if method == "GET"but GET is the default. If user explicitly passes--method GET, the prompt still shows.Fix: Change to
if !c.IsSet("method")M12:
cronjobs updatesilently ignores JSON unmarshal errorFile:
cmd/cronjobs/cronjobs_update.go:57Problem:
_ = json.Unmarshal(*existing.Settings, ¤tSettings)— if settings JSON is malformed, zero values silently overwrite.Fix: Check the error:
if err := json.Unmarshal(...); err != nil { return fmt.Errorf("could not parse existing settings: %w", err) }M-extra:
cronjobs update—defaultMethodunused in interactive selectFile:
cmd/cronjobs/cronjobs_update.go:112Problem:
_ = defaultMethod— the current method is computed but not used as the default selection.Fix: Use
pterm.DefaultInteractiveSelect.WithDefaultOption(defaultMethod)Acceptance Criteria
createos domains delete --project X --domain Y --force | catenv/helpers.goandscale.goselect loops have fallthrough guardsoauth-clients deletein READMEgo build ./...andgo vet ./...pass