Skip to content

UX: collapse 'supermodel setup' and bare 'supermodel' into one command for first-run users #151

@jonathanpopham

Description

@jonathanpopham

The problem

Today there are two commands a new user has to know about:

  • `supermodel setup` — interactive wizard: auth, repo detection, hook offer, shard mode, then drops into watch
  • `supermodel` (bare) — runs the watch daemon, requires an API key already configured

So the canonical first-run path is three commands:

```bash
curl -fsSL https://supermodeltools.com/install.sh | sh
cd /path/to/repo
supermodel setup
```

…and then to restart watch later, the user has to remember a different command (`supermodel`) than the one they used to onboard. That's friction.

There's no fundamental reason for the split. The setup wizard already calls `shards.Watch(...)` at the end of its happy path (`internal/setup/wizard.go:197`), so a bare invocation that detected "no config" could just hand off to setup and end up in the same place.

Proposed UX

One command, dispatched on state:

Situation Behavior
Interactive TTY, no API key configured Launch the setup wizard (browser auth → wizard → watch)
Interactive TTY, API key already configured Run watch daemon (current behavior)
Non-interactive (CI, headless), no API key Exit with the existing error: `not authenticated — run \supermodel setup\\ or set SUPERMODEL_API_KEY`
Non-interactive, API key set via env or config Run watch daemon (current behavior)

`supermodel setup` stays as an explicit "redo the wizard" entry point for power users who want to re-auth, reinstall the hook, or change shard mode. We just stop requiring it for first-time users.

After the change, the quickstart collapses to:

```bash
curl -fsSL https://supermodeltools.com/install.sh | sh
cd /path/to/repo
supermodel
```

Sketch in `cmd/root.go`

```go
RunE: func(cmd *cobra.Command, args []string) error {
cfg, err := config.Load()
if err != nil || cfg.APIKey == "" {
if isInteractive() { // term.IsTerminal(int(os.Stdin.Fd()))
return setup.Run(cmd.Context(), cfg) // wizard already ends in shards.Watch
}
return fmt.Errorf("not authenticated — run \supermodel setup\\ or set SUPERMODEL_API_KEY")
}
// existing watch path
return shards.Watch(cmd.Context(), cfg, dir, opts)
}
```

Tracking checklist

  • Land the dispatch logic in `cmd/root.go`
  • Add a test: TTY + empty config → wizard runs (mock)
  • Add a test: non-TTY + empty config → exits with auth error, does not block
  • Add a test: any context + valid config → goes straight to watch
  • Update `README.md` quickstart to the single-command form
  • Update `internal/setup/wizard.go` exit message ("Run \supermodel\\ to restart") — already part of Replace stale 'supermodel watch' references with 'supermodel' #150
  • Update docs at supermodeltools/docs (`/cli/install`, `/cli/quickstart`, intro page) to drop the 3-step flow
  • Decide whether the install-time `first-run setup wizard` (Add first-run detection and install-time setup wizard #49) is now redundant — it might be, if the same path runs the first time the user types `supermodel` in a repo

Edge cases worth thinking about

  1. `supermodel` invoked in a repo that already has stale `.graph.*` files from an earlier user. Today `analyze` reuses cache by content hash, so that's already fine — just noting.
  2. `supermodel ./some/repo` (positional path) on first run. The wizard currently detects the git root from cwd; would need to honor the positional arg if used.
  3. `SUPERMODEL_API_KEY` set in env but no `config.yaml`. Should still skip the wizard and run watch — env-based auth is a valid "already configured" state.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions