Address the review findings on the CLI surface: * `pic login` now prompts for username + password and POSTs to `/api/v1/admin/auth/login`. `--token` (and `PICLOUD_TOKEN`) still works for paste-a-bearer flows (CI, long-lived API keys). Falls back to a plain stdin read when no controlling tty is attached. * `pic logout` revokes the session server-side and deletes the local credentials file. Idempotent. * `PICLOUD_URL` / `PICLOUD_TOKEN` now override the on-disk credentials file for every command via `config::resolve`, not just for `pic login`. Matches gcloud/aws/kubectl semantics. * New commands: `pic apps delete [--force]`, `pic apps show`, `pic scripts delete`, `pic api-keys mint|ls|rm`, plus top-level `pic invoke` / `pic deploy` shortcuts. * `pic scripts ls` (no `--app`) now issues a single `GET /admin/scripts` + one `apps_list` in parallel and joins client-side, instead of walking N+1 per-app calls that aborted on the first 404 — the bug the test suite was retrying around. * Global `--output tsv|json` flag wired through every list/show and through `whoami` / `logs`. TSV stays pipe-friendly; JSON is a real array of objects (or a flat object for single-row views). * `whoami` and `logs` now emit labeled output instead of headerless tab lines, consistent with the existing `apps ls` / `scripts ls`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
35 lines
1.1 KiB
Rust
35 lines
1.1 KiB
Rust
//! `pic whoami` — re-validates the saved token by hitting `/auth/me`
|
|
//! every time. Cached username in the credentials file is for
|
|
//! display-only contexts; this command is the source of truth.
|
|
//!
|
|
//! TSV output uses `KvBlock` (aligned `key: value` rows), JSON output
|
|
//! is a flat object — both downstream-friendly without the user having
|
|
//! to parse a headerless tab-line.
|
|
|
|
use anyhow::Result;
|
|
use picloud_shared::InstanceRole;
|
|
|
|
use crate::client::Client;
|
|
use crate::config;
|
|
use crate::output::{KvBlock, OutputMode};
|
|
|
|
pub async fn run(mode: OutputMode) -> Result<()> {
|
|
let creds = config::resolve()?;
|
|
let client = Client::from_creds(&creds)?;
|
|
let me = client.auth_me().await?;
|
|
let role = match me.instance_role {
|
|
InstanceRole::Owner => "owner",
|
|
InstanceRole::Admin => "admin",
|
|
InstanceRole::Member => "member",
|
|
};
|
|
let email = me.email.as_deref().unwrap_or("-");
|
|
let mut block = KvBlock::new();
|
|
block
|
|
.field("username", me.username)
|
|
.field("role", role)
|
|
.field("email", email)
|
|
.field("url", creds.url.clone());
|
|
block.print(mode);
|
|
Ok(())
|
|
}
|