/** * Saying why a Google grant stopped working, instead of trying it again. * * The defect this exists to fix: a refresh returned `invalid_grant` and the * agent retried the identical request six times. Every attempt was guaranteed * to fail, `invalid_grant` is Google's way of saying the token is not coming * back, ever, and none of the six produced a single word about why. The * person watching learned nothing across six round trips. * * `invalid_grant` has a small number of real causes and they need different * things from the person, so guessing between them silently is the worst * option. This module names the likely one in plain words and says what to do, * and `token-manager.ts` latches on the result so the same dead refresh is * never sent a second time. * * The most common cause by far is the account trap: the consent screen was * approved while signed in as a personal Google account, so the refresh token * belongs to a different identity than the one the product is configured for. * Nothing about that is visible in Google's error text, which is why this * takes the intended account and the signed-in account as inputs and compares * them itself. */ /** Why a grant is no longer usable. */ export type GoogleGrantFailureCause = /** The token was minted under a different Google account than the configured one. */ 'account-mismatch' /** The person (or Google) revoked the grant, or it aged out. */ | 'revoked' /** The refresh token does not belong to the client id being used with it. */ | 'client-mismatch' /** The app is still in Testing, so the token expired seven days after issue. */ | 'testing-expiry' /** None of the signatures matched. The candidates are still stated. */ | 'unknown'; export interface GoogleGrantDiagnosis { readonly cause: GoogleGrantFailureCause; /** Plain words. Never a token, never a raw Google error alone. */ readonly problem: string; /** What to do, naming a command that exists. */ readonly fix: string; /** True for every cause here, a dead grant always needs a person. */ readonly needsReauthorization: true; } export interface GrantDiagnosisInput { /** Google's own error text, used only as a signature. May be empty. */ readonly googleError: string; /** The account this product is configured for, when known. */ readonly intendedAccount: string | null; /** The account the machine is actually signed in as (gcloud), when known. */ readonly signedInAccount: string | null; /** Last known publishing status, which decides whether a 7-day fuse applies. */ readonly publishingStatus: 'testing' | 'in-production' | 'unknown'; /** Where the credential came from, which changes the remedy wording. */ readonly credentialOrigin: 'secret-store' | 'gmail-mcp' | null; } /** * Work out the likely cause and say it. * * Ordered most-specific first: a signature Google actually gave us beats an * inference, and an account mismatch we can see for ourselves beats a generic * "it expired". Every branch returns a fix naming a real command. */ export declare function diagnoseInvalidGrant(input: GrantDiagnosisInput): GoogleGrantDiagnosis; /** The diagnosis as lines for a transcript. Problem first, then the remedy. */ export declare function describeGrantDiagnosis(diagnosis: GoogleGrantDiagnosis): readonly string[]; //# sourceMappingURL=grant-diagnosis.d.ts.map