Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/deprecate-api-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@smooai/smooth': patch
---

th-9cd759: `th api login/logout/whoami` now print deprecation warnings pointing at `th auth login --m2m` / `th auth logout --m2m` / `th auth whoami` (removal after one release cycle); docs updated to the `th auth` spellings.
40 changes: 31 additions & 9 deletions crates/smooth-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,11 +598,23 @@ enum OrgsCommands {
},
}

/// Pearl th-9cd759: `th api login/logout/whoami` moved to the `th auth`
/// surface. One release cycle of warnings, then the three arms get removed
/// (the `th api <resource>` operations stay — they aren't auth).
fn deprecated_api_auth_hint(old: &str, new: &str) {
use owo_colors::OwoColorize;
eprintln!(
"{} `th api {old}` is deprecated and will be removed in a future release — use `{new}`",
"warning:".yellow().bold()
);
}

#[derive(Subcommand)]
enum ApiCommands {
/// Authenticate `th` against the Smoo AI platform API. Exchanges
/// an OAuth2 client_credentials grant at `https://auth.smoo.ai/token`
/// for a bearer JWT and stores it at `~/.smooth/auth/smooai.json`.
/// DEPRECATED — use `th auth login --m2m`. Authenticate `th` against
/// the Smoo AI platform API. Exchanges an OAuth2 client_credentials
/// grant at `https://auth.smoo.ai/token` for a bearer JWT and stores
/// it at `~/.smooth/auth/smooai.json`.
///
/// Credential resolution order (first present wins):
/// 1. `--client-id` + `--client-secret` flags
Expand All @@ -617,10 +629,11 @@ enum ApiCommands {
#[arg(long)]
client_secret: Option<String>,
},
/// Forget the current Smoo AI platform session — deletes
/// `~/.smooth/auth/smooai.json`. Idempotent.
/// DEPRECATED — use `th auth logout --m2m`. Forget the current Smoo AI
/// platform session — deletes `~/.smooth/auth/smooai.json`. Idempotent.
Logout,
/// Print the currently-logged-in Smoo AI user + active org.
/// DEPRECATED — use `th auth whoami`. Print the currently-logged-in
/// Smoo AI user + active org.
Whoami,
/// Smoo AI organization management.
Orgs {
Expand Down Expand Up @@ -1390,9 +1403,18 @@ async fn main() -> Result<()> {
#[cfg(feature = "admin")]
Some(Commands::Admin { cmd }) => admin::dispatch(cmd).await,
Some(Commands::Api { cmd }) => match cmd {
ApiCommands::Login { client_id, client_secret } => cmd_login(client_id, client_secret).await,
ApiCommands::Logout => cmd_logout().await,
ApiCommands::Whoami => cmd_whoami().await,
ApiCommands::Login { client_id, client_secret } => {
deprecated_api_auth_hint("login", "th auth login --m2m");
cmd_login(client_id, client_secret).await
}
ApiCommands::Logout => {
deprecated_api_auth_hint("logout", "th auth logout --m2m");
cmd_logout().await
}
ApiCommands::Whoami => {
deprecated_api_auth_hint("whoami", "th auth whoami");
cmd_whoami().await
}
ApiCommands::Orgs { cmd } => cmd_orgs(cmd).await,
ApiCommands::Agents { cmd } => smooai::agents::cmd(cmd).await,
ApiCommands::Keys { cmd } => smooai::keys::cmd(cmd).await,
Expand Down
14 changes: 7 additions & 7 deletions docs/Engineering/Using-th-CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ The Smoo AI platform uses a two-tier identity model that `th` mirrors exactly:
### Logging in today (M2M client_credentials)

```bash
th api login # interactive — prompts for client_id + secret
SMOOAI_CLIENT_ID=… SMOOAI_CLIENT_SECRET=… th api login # env-driven (CI, scripts)
th api login --client-id=… --client-secret=… # flag-driven
th auth login --m2m # interactive — prompts for client_id + secret
SMOOAI_CLIENT_ID=… SMOOAI_CLIENT_SECRET=… th auth login --m2m # env-driven (CI, scripts)
th auth login --m2m --client-id=… --client-secret=… # flag-driven
```

Credential resolution order (first present wins):
Expand All @@ -77,7 +77,7 @@ The exchange happens against `https://auth.smoo.ai/token` with `grant_type=clien
### Verifying you're logged in

```bash
th api whoami
th auth whoami
# Identity client:bee846cc-... ← the M2M client_id (or user:… if dashboard auth)
# Email brent@smoo.ai
# Admin roles super_admin (1) ← present iff your client/user has admin grants
Expand Down Expand Up @@ -118,7 +118,7 @@ Practical consequences:
### Logout

```bash
th api logout # deletes ~/.smooth/auth/smooai.json (idempotent)
th auth logout --m2m # deletes ~/.smooth/auth/smooai.json (idempotent)
```

### Provider auth is separate
Expand Down Expand Up @@ -743,7 +743,7 @@ Both repos ship a `PreToolUse` Bash hook (`.claude/hooks/th-curl-hint.sh`) that
| Pattern | Hint |
|---|---|
| `curl … api.smoo.ai` | Use `th api …` instead |
| `curl … auth.smoo.ai/token` | Use `th api login` instead |
| `curl … auth.smoo.ai/token` | Use `th auth login --m2m` instead |
| `curl … atlassian.net/rest/api` | Use `th jira sync` (or file a pearl for the missing verb) |
| `gh secret set … --body -` with stdin echo | Use `scripts/secret-helpers/gh-secret-set` to avoid trailing-newline corruption |
| `pnpm sst secret list` (raw) | Use `scripts/secret-helpers/sst-secret-list` to avoid plaintext leakage |
Expand Down Expand Up @@ -771,7 +771,7 @@ The `th` binary is built from this repo. Every gap is a `th-*` pearl waiting to

```bash
# Identity
th api whoami # who am I, which org, when does my JWT expire
th auth whoami # who am I, which org, when does my JWT expire
th api orgs list # what orgs can I see
th api orgs switch <id> # change active org

Expand Down
Loading