Skip to content

feat(cli): structured error for non-interactive workspace selection#68

Open
ItamarZand88 wants to merge 1 commit into
mainfrom
itamar/alien-154-cli-guide-agents-through-workspace-selection-after-login
Open

feat(cli): structured error for non-interactive workspace selection#68
ItamarZand88 wants to merge 1 commit into
mainfrom
itamar/alien-154-cli-guide-agents-through-workspace-selection-after-login

Conversation

@ItamarZand88
Copy link
Copy Markdown
Contributor

@ItamarZand88 ItamarZand88 commented Jun 2, 2026

Summary

When something automated runs alien login — an agent like Claude, a script, anything without a real terminal — it can't use the arrow-key menu to pick a workspace. Before, it hit a dead end ("needs a real terminal"). Now it gets the actual list of workspaces back, so it can pick one with a follow-up command.

What an agent sees when it runs alien login:

  1. The browser opens and you log in — same as always.
  2. It needs a workspace but can't show the menu, so it returns WORKSPACE_SELECTION_REQUIRED with the names under context.workspaces. ← the new bit
  3. It reads the names and runs alien workspaces set <name>.

So instead of a dead-end string, you get back something a machine can act on. I also removed alien login --json — an agent can get the same list from alien workspaces ls --json, so login didn't need its own JSON mode.

How I tested it

On a local stack, logged in fresh, on an account with 3 workspaces:

  • Ran alien login, finished in the browser — it ended on WORKSPACE_SELECTION_REQUIRED with the 3 names and a hint pointing at alien workspaces ls / set.
  • alien workspaces ls --json gave the list, alien workspaces set <name> saved it, alien workspaces current confirmed it.
  • alien login --json now says "unexpected argument".
  • cargo test -p alien-cli --features platform is green, including a test that checks the names actually land in context.workspaces.

At the workspace-selection step, a non-interactive caller (no TTY or
--json, with >=2 workspaces) now gets WORKSPACE_SELECTION_REQUIRED listing
the workspaces under context.workspaces, instead of a plain "requires a real
terminal" string. The caller re-runs with `alien workspaces set <name>`. The
interactive arrow-key menu is unchanged.

Also remove `alien login --json`: structured workspace data comes from
`alien workspaces ls --json`, so a JSON mode on login is redundant.
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 2, 2026

Greptile Summary

This PR replaces the opaque "requires a real terminal" string error in prompt_workspace with a machine-readable WORKSPACE_SELECTION_REQUIRED error that carries the available workspace names in context.workspaces, and removes the now-redundant --json flag from alien login.

  • error.rs: New WorkspaceSelectionRequired { workspaces: Vec<String> } variant exposes workspace names in the structured error context; accompanied by a unit test that validates the context.workspaces array via AlienErrorData.
  • workspace.rs: prompt_workspace now calls InteractionMode::current(json_mode).is_machine() instead of require_prompt, returning the new typed error when running non-interactively; login.rs hardcodes json_mode = false (correct since --json is removed from login).
  • lib.rs / login.rs: LoginArgs is reduced to a fieldless struct, wants_json_output returns false for Login, and the JSON output branch is deleted — a deliberate breaking change for callers that used alien login --json.

Confidence Score: 5/5

The change is a tightly scoped error-type upgrade with no mutations to auth logic and no new async paths; safe to merge.

All changed paths are narrow: the new structured error is only returned when multiple workspaces exist and the caller is non-interactive, the single-workspace fast path is untouched, and the removal of --json from alien login is intentional and self-consistent. The test directly exercises the context.workspaces payload. No auth state is modified before the error is returned.

No files require special attention.

Important Files Changed

Filename Overview
crates/alien-cli/src/commands/platform/login.rs Removes the --json flag and LoginOutput struct from alien login; simplifies login_task to always emit human-readable output and forwards json_mode=false to prompt_workspace.
crates/alien-cli/src/commands/platform/workspace.rs Replaces the generic require_prompt ConfigurationError with a structured WorkspaceSelectionRequired error when InteractionMode::current detects machine mode; drops can_prompt import since it is now called internally by InteractionMode::current.
crates/alien-cli/src/error.rs Adds WorkspaceSelectionRequired error variant carrying Vec workspaces and a unit test that asserts the variant serializes context.workspaces correctly via AlienErrorData.
crates/alien-cli/src/lib.rs Updates wants_json_output to return false for Login commands (destructuring the now-fieldless LoginArgs with _); consistent with the removal of the --json flag.
crates/alien-cli/src/ui.rs Renames the test module from tests to command_event_tests to avoid a name collision, no functional change.

Sequence Diagram

sequenceDiagram
    participant Agent
    participant CLI as alien CLI
    participant Auth as force_login
    participant API as Platform API
    participant Browser

    Note over Agent,Browser: New non-interactive workspace-selection flow

    Agent->>CLI: alien login (no TTY)
    CLI->>Auth: force_login()
    Auth->>Browser: open OAuth URL
    Browser-->>Auth: token callback
    Auth-->>CLI: AuthHttp

    CLI->>API: list_workspaces()
    API-->>CLI: ["ws-a", "ws-b", "ws-c"]

    Note over CLI: workspaces.len() > 1 AND is_machine() == true
    CLI-->>Agent: WORKSPACE_SELECTION_REQUIRED context.workspaces: ["ws-a","ws-b","ws-c"]

    Agent->>CLI: alien workspaces set ws-a
    CLI->>API: validate_workspace_name("ws-a")
    API-->>CLI: ok
    CLI->>CLI: save_workspace("ws-a")
    CLI-->>Agent: workspace saved

    Note over Agent,Browser: Single-workspace or interactive flow (unchanged)
    Agent->>CLI: alien login (single workspace)
    CLI->>Auth: force_login()
    Auth-->>CLI: AuthHttp
    CLI->>API: list_workspaces()
    API-->>CLI: ["ws-a"]
    Note over CLI: workspaces.len() == 1 - auto-select
    CLI->>CLI: save_workspace("ws-a")
    CLI-->>Agent: human-readable success output
Loading

Reviews (1): Last reviewed commit: "feat(cli): structured error for non-inte..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant