Skip to content

Default CLI login to org SSO; drop the --workos vendor flag - #177

Merged
alexeyzimarev merged 6 commits into
mainfrom
alexeyzimarev/login-default-workos-drop-vendor-flag
Jun 25, 2026
Merged

alexeyzimarev merged 6 commits into
mainfrom
alexeyzimarev/login-default-workos-drop-vendor-flag

Conversation

@alexeyzimarev

Copy link
Copy Markdown
Member

What & why

kcap login/kcap setup exposed the auth vendor to users via the --workos flag. Vendor naming shouldn't leak into the user-facing CLI. New model: org SSO is the default sign-in; GitHub is the explicit opt-in via --github.

Changes

  • OAuthLoginFlow.ChooseDiscoveryProvider now returns a concrete provider (no nullable "prompt" signal): --github → GitHub App; no-flag interactive → org SSO (WorkOS); no-flag headless → GitHub device flow (WorkOS needs a browser loopback). --workos is no longer recognized.
  • Deleted the interactive DiscoveryProviderPrompt picker; login (Program.cs) and setup (SetupCommand.cs) resolve the provider directly.
  • help-login.txt + README.md: usage [--discover] [--github] [--device], SSO-by-default wording, --workos removed, gratuitous "WorkOS" naming scrubbed (internal AuthProvider.WorkOS protocol constant kept).

Backward-compatible: a stale --workos is now a harmless no-op (interactive callers still land on the SSO default).

Tests

  • ChooseDiscoveryProvider_honors_flags_and_default updated to the new contract.
  • Unit 1695/0, integration 37/0, dotnet publish -c Release IL-clean, kcap login --help shows no --workos.

Spec: docs/superpowers/specs/2026-06-25-login-default-workos-design.md · Plan: docs/superpowers/plans/2026-06-25-login-default-workos.md

🤖 Generated with Claude Code

alexeyzimarev and others added 5 commits June 25, 2026 13:05
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Default kcap login/setup to org SSO; remove user-facing --workos flag
✨ Enhancement 📝 Documentation 🧪 Tests 🕐 20-40 Minutes

Grey Divider

Description

• Make org SSO the default discovery/login path; require --github to opt into GitHub.
• Remove the interactive provider picker and resolve the provider in login/setup directly.
• Update help text and README to drop --workos and scrub vendor naming.
Diagram

graph TD
  docs["Docs (README/help)"] --> cli["CLI (login/setup)"] --> oauth["OAuthLoginFlow"] --> choose{"Pick provider"}
  headless["HeadlessEnvironment"] --> oauth
  choose -->|"--github"| github["GitHub App/device"]
  choose -->|"default (interactive)"| sso["Org SSO (WorkOS)"]
  choose -->|"default (headless)"| github
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep --workos as hidden deprecated alias (warn once)
  • ➕ Reduces confusion for users with old scripts or muscle memory
  • ➕ Gives a cleaner migration path with explicit feedback
  • ➖ Adds legacy surface area the PR is trying to remove
  • ➖ Requires plumbing argument detection/warning output across commands
2. Introduce an explicit --sso (or --org-sso) flag
  • ➕ Avoids vendor naming while still allowing explicit selection symmetry with --github
  • ➕ Makes behavior explicit in scripts without relying on interactive defaults
  • ➖ Adds another flag to maintain and document
  • ➖ Still exposes provider choice that may be intended to stay implicit

Recommendation: The PR’s approach (SSO-by-default, explicit --github opt-in, no provider prompt) is the simplest CLI surface and aligns with the stated product model. Consider optionally detecting a passed --workos and emitting a one-time deprecation warning; otherwise, the current “harmless no-op” behavior is acceptable if the CLI generally ignores unknown flags.

Files changed (8) +389 / -27

Enhancement (3) +8 / -11
OAuthLoginFlow.csMake discovery provider selection non-null with SSO interactive default +6/-9

Make discovery provider selection non-null with SSO interactive default

• Changes ChooseDiscoveryProvider to always return a concrete provider (string instead of nullable). Removes --workos handling and makes interactive no-flag default to WorkOS (org SSO), while keeping headless no-flag fallback to GitHub.

src/Capacitor.Cli.Core/Auth/OAuthLoginFlow.cs

SetupCommand.csResolve discovery provider directly in setup (no interactive picker) +1/-1

Resolve discovery provider directly in setup (no interactive picker)

• Replaces DiscoveryProviderPrompt usage with a direct call to OAuthLoginFlow.ChooseDiscoveryProvider using headless detection to set isInteractive. Keeps downstream branching on provider (WorkOS vs GitHub) intact.

src/Capacitor.Cli/Commands/SetupCommand.cs

Program.csResolve discovery provider directly in login (no interactive picker) +1/-1

Resolve discovery provider directly in login (no interactive picker)

• Removes the intermediate prompt resolver and calls OAuthLoginFlow.ChooseDiscoveryProvider directly, passing isInteractive derived from HeadlessEnvironment. Leaves provider-specific execution paths unchanged.

src/Capacitor.Cli/Program.cs

Tests (1) +2 / -3
OAuthFlowTests.csUpdate ChooseDiscoveryProvider unit test for SSO-by-default contract +2/-3

Update ChooseDiscoveryProvider unit test for SSO-by-default contract

• Removes assertions for --workos and the prior interactive-null (“prompt”) behavior. Adds assertions that interactive no-flag defaults to WorkOS and headless no-flag defaults to GitHub.

test/Capacitor.Cli.Tests.Unit/OAuthFlowTests.cs

Documentation (4) +379 / -13
README.mdUpdate setup/login docs to SSO-by-default and remove vendor references +3/-3

Update setup/login docs to SSO-by-default and remove vendor references

• Rewords tenant discovery and login descriptions to default to organization SSO and make GitHub an explicit --github opt-in. Removes references to WorkOS/GitHub provider picking and drops mention of --workos.

README.md

2026-06-25-login-default-workos.mdAdd implementation plan for SSO-default login and --workos removal +250/-0

Add implementation plan for SSO-default login and --workos removal

• Introduces a step-by-step plan covering code changes, test updates, doc updates, and verification gates (AOT cleanliness, grep checks). Captures intended contracts for provider selection and caller rewiring.

docs/superpowers/plans/2026-06-25-login-default-workos.md

2026-06-25-login-default-workos-design.mdAdd design spec for new provider-selection contract and flag surface +117/-0

Add design spec for new provider-selection contract and flag surface

• Documents the rationale for removing vendor naming from the CLI, defines the new ChooseDiscoveryProvider decision table, and enumerates non-goals and verification steps. Calls out deletion of the interactive picker and required doc rewrites.

docs/superpowers/specs/2026-06-25-login-default-workos-design.md

help-login.txtRevise login help: drop --workos and describe SSO-by-default discovery +9/-10

Revise login help: drop --workos and describe SSO-by-default discovery

• Updates usage to remove the --workos option and rewrites discovery copy to default to organization SSO with --github as the override. Adjusts option descriptions to match the new behavior and removes vendor-specific wording.

src/Capacitor.Cli.Core/Resources/help-login.txt

@qodo-code-review

qodo-code-review Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Setup help omits --github ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
SetupCommand accepts --github (via ChooseDiscoveryProvider) and, after removing the
interactive picker, it’s the only way to opt into GitHub discovery in browser-capable interactive
environments. However help-setup.txt doesn’t document --github, so kcap setup --help won’t
expose the flag that now controls an important behavior branch.
Code

src/Capacitor.Cli/Commands/SetupCommand.cs[410]

+        var provider = OAuthLoginFlow.ChooseDiscoveryProvider(args, isInteractive: !HeadlessEnvironment.IsHeadless());
Evidence
The setup discovery code path uses ChooseDiscoveryProvider (which honors --github), but `kcap
setup --help prints help-setup.txt, whose option list currently lacks --github`.

src/Capacitor.Cli/Commands/SetupCommand.cs[396-425]
src/Capacitor.Cli.Core/Auth/OAuthLoginFlow.cs[55-65]
src/Capacitor.Cli.Core/Resources/help-setup.txt[3-12]
src/Capacitor.Cli/Program.cs[64-67]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`kcap setup --help` doesn’t mention `--github`, but `kcap setup` still supports it and it’s now the only user-facing way to choose GitHub discovery in interactive/browser-capable runs (since the provider picker was deleted).

### Issue Context
`Program.cs` serves `help-setup.txt` for `kcap setup --help`. `SetupCommand.RunDiscoveryAsync` passes raw args into `OAuthLoginFlow.ChooseDiscoveryProvider`, which checks for `--github`.

### Fix Focus Areas
- src/Capacitor.Cli.Core/Resources/help-setup.txt[3-12]
- src/Capacitor.Cli/Commands/SetupCommand.cs[396-413]
- src/Capacitor.Cli/Program.cs[64-67]

### What to change
Add an option line to `help-setup.txt`, e.g.:
- `--github                    Use GitHub for tenant discovery (default is org SSO when a browser is available).`
Optionally add one short sentence noting that this only affects the discovery step when no `--server-url`/tenant argument is provided.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Docs miss headless fallback ✓ Resolved 🐞 Bug ≡ Correctness
Description
help-login.txt and README.md state tenant discovery signs in with org SSO by default and
--github is the GitHub opt-in, but OAuthLoginFlow.ChooseDiscoveryProvider selects GitHubApp
whenever the environment is headless (e.g., SSH/no DISPLAY). This makes headless/SSH behavior
diverge from the documented default and can confuse scripted/remote users who expect SSO sign-in.
Code

src/Capacitor.Cli.Core/Resources/help-login.txt[R7-12]

With no configured server (or with --discover), kcap runs tenant discovery:
-you choose how to sign in — "Continue" (email / SSO) or "Continue with
-GitHub" — authenticate once, then pick from the tenants you belong to. No
---server-url and no existing profile are required. With a server already
-configured, kcap logs into it directly (the auth method — GitHub App or
-WorkOS — is auto-discovered from the server's /auth/config).
+it signs you in with your organization's single sign-on, then lets you pick
+from the tenants you belong to. No --server-url and no existing profile are
+required. Pass --github to sign in with GitHub instead. With a server already
+configured, kcap logs into it directly (the sign-in method is auto-discovered
+from the server's /auth/config).
Evidence
Docs claim SSO default for discovery, but the resolver returns GitHub in headless/SSH scenarios due
to HeadlessEnvironment.IsHeadless(), and callers wire isInteractive as the negation of that
headless heuristic.

src/Capacitor.Cli.Core/Resources/help-login.txt[7-12]
README.md[60-63]
README.md[137-144]
src/Capacitor.Cli.Core/Auth/OAuthLoginFlow.cs[55-65]
src/Capacitor.Cli.Core/Auth/HeadlessEnvironment.cs[12-21]
src/Capacitor.Cli/Program.cs[654-670]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The user-facing docs (`help-login.txt`, `README.md`) currently describe discovery as “SSO by default; `--github` opts into GitHub”, but the actual behavior is: **headless/SSH defaults to GitHub** (device flow) because WorkOS requires a browser loopback.

### Issue Context
`OAuthLoginFlow.ChooseDiscoveryProvider` returns `AuthProvider.GitHubApp` when `isInteractive` is false, and callers pass `isInteractive: !HeadlessEnvironment.IsHeadless()`. `HeadlessEnvironment` marks SSH sessions (and Linux without DISPLAY/WAYLAND) as headless.

### Fix Focus Areas
- src/Capacitor.Cli.Core/Resources/help-login.txt[7-12]
- README.md[62-63]
- README.md[143-143]
- src/Capacitor.Cli.Core/Auth/OAuthLoginFlow.cs[55-65]
- src/Capacitor.Cli.Core/Auth/HeadlessEnvironment.cs[12-21]

### What to change
Update the discovery wording to explicitly mention the headless exception, e.g.:
- “Defaults to org SSO when a browser is available; in SSH/headless environments discovery falls back to GitHub Device Flow.”
- Keep `--github` wording, but clarify it’s the explicit opt-in for GitHub in interactive/browser-capable environments.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

…etup help

Addresses Qodo review on #177:
- help-login.txt + README: discovery falls back to GitHub Device Flow in
  SSH/headless environments (SSO needs a local browser) — docs previously
  implied SSO unconditionally
- help-setup.txt: document --github (now the only way to pick GitHub in setup
  after the interactive picker was removed)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alexeyzimarev
alexeyzimarev merged commit c7711b1 into main Jun 25, 2026
5 checks passed
@alexeyzimarev
alexeyzimarev deleted the alexeyzimarev/login-default-workos-drop-vendor-flag branch June 25, 2026 11:51
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