diff --git a/cmd/profile/profile.go b/cmd/profile/profile.go index 4f2976126..616ba440b 100644 --- a/cmd/profile/profile.go +++ b/cmd/profile/profile.go @@ -18,7 +18,7 @@ func NewCmdProfile(f *cmdutil.Factory) *cobra.Command { Profile selection: lark-cli whoami --json Show the app/profile lark-cli is using now. - lark-cli auth status --json Verify OAuth login and token state. + lark-cli auth status --json --verify Verify OAuth login and token state. --profile Use a profile for this command only. LARKSUITE_CLI_PROFILE Use a profile for the current shell / agent session. config show / profile list Inspect saved config, not current usage. diff --git a/errs/ERROR_CONTRACT.md b/errs/ERROR_CONTRACT.md index 5262ce58d..383a64053 100644 --- a/errs/ERROR_CONTRACT.md +++ b/errs/ERROR_CONTRACT.md @@ -67,6 +67,17 @@ Typed errors render to **stderr** as one JSON object per process exit: | `error.params` | per-Subtype-stable | per-parameter validation detail array (`ValidationError`); see **Validation parameters** | | per-Subtype extension fields | per-Subtype-stable | e.g. `missing_scopes`, `console_url`, `challenge_url` | +Credential/identity-selection extension fields (per-Subtype-stable): + +| Field | Carrier | Subtypes | Notes | +|-------|---------|----------|-------| +| `missing_keys` | `ConfigError` | `app_credential_incomplete` | env var NAMES that must all be set; never values | +| `required_any_of` | `ConfigError` | `app_credential_incomplete` | env var NAMES where any one completes the credential; mutually exclusive with `missing_keys` | +| `profile` | `ConfigError` | `profile_not_found`, `profile_secret_invalid` | requested profile name | +| `app_id` | `ConfigError` | `profile_secret_invalid` | plaintext app id; never a secret | +| `credential_source` | `ConfigError` | `profile_not_found`, `no_active_profile` | how the identity was (not) chosen: `flag:--profile` \| `env:LARKSUITE_CLI_PROFILE` \| `config` | +| `profile_app_id`, `env_app_id` | `ValidationError` | `profile_app_credential_conflict` | the two conflicting plaintext app ids | + `SecurityPolicyError` renders through the same typed envelope as every other category. `error.type` is `"policy"`, `error.subtype` is one of `challenge_required` / `access_denied`, and process exit is `6` via diff --git a/errs/types.go b/errs/types.go index f37888e77..027c9d543 100644 --- a/errs/types.go +++ b/errs/types.go @@ -331,7 +331,7 @@ type ConfigError struct { // CredentialSource is the machine-readable App/credential selection source // that produced this config error (e.g. "flag:--profile", // "env:LARKSUITE_CLI_PROFILE", "config"). It is required on - // profile_not_found and no_active_profile (spec §5) so an agent can branch + // profile_not_found and no_active_profile so an agent can branch // on how the identity was (or was not) chosen. It is never a secret. CredentialSource string `json:"credential_source,omitempty"` Cause error `json:"-"` diff --git a/internal/cmdutil/factory_default.go b/internal/cmdutil/factory_default.go index bcd80652c..5a5a76516 100644 --- a/internal/cmdutil/factory_default.go +++ b/internal/cmdutil/factory_default.go @@ -193,6 +193,10 @@ func buildCredentialProvider(deps credentialDeps) *credential.CredentialProvider // provider clears unverified identity fields), so silencing the // warning is safe. cred := credential.NewCredentialProvider(providers, defaultAcct, defaultToken, deps.HttpClient) + if deps.Profile == "" { + // No profile selected — don't record a phantom env source. + return cred + } if deps.ProfileFromFlag { return cred.WithProfileFromFlag(deps.Profile) }