Skip to content

Improve agent guidance for store auth#7657

Draft
gonzaloriestra wants to merge 1 commit into
agent-auth/resumable-loginfrom
agent-auth/improve-store-auth-guidance
Draft

Improve agent guidance for store auth#7657
gonzaloriestra wants to merge 1 commit into
agent-auth/resumable-loginfrom
agent-auth/improve-store-auth-guidance

Conversation

@gonzaloriestra
Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Fixes #0000

WHAT is this pull request doing?

How to test your changes?

Post-release steps

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@gonzaloriestra gonzaloriestra force-pushed the agent-auth/improve-store-auth-guidance branch from 12ce355 to 9772ca8 Compare May 28, 2026 14:29
Copy link
Copy Markdown
Contributor Author

/snapit

@github-actions github-actions Bot added no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. and removed Area: @shopify/cli @shopify/cli package issues labels May 28, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/public/common/version.d.ts
@@ -1 +1 @@
-export declare const CLI_KIT_VERSION = "4.1.0";
\ No newline at end of file
+export declare const CLI_KIT_VERSION = "4.0.0";
\ No newline at end of file
packages/cli-kit/dist/private/node/conf-store.d.ts
@@ -18,6 +18,13 @@ interface Cache {
     [mostRecentOccurrenceKey: MostRecentOccurrenceKey]: CacheValue<boolean>;
     [rateLimitKey: RateLimitKey]: CacheValue<number[]>;
 }
+export interface PendingDeviceAuth {
+    deviceCode: string;
+    userCode: string;
+    verificationUriComplete: string;
+    interval: number;
+    expiresAt: number;
+}
 export interface ConfSchema {
     sessionStore: string;
     currentSessionId?: string;
@@ -25,6 +32,7 @@ export interface ConfSchema {
     currentDevSessionId?: string;
     cache?: Cache;
     autoUpgradeEnabled?: boolean;
+    pendingDeviceAuth?: PendingDeviceAuth;
 }
 /**
  * Get session.
@@ -58,6 +66,22 @@ export declare function setCurrentSessionId(sessionId: string, config?: LocalSto
  * Remove current session ID.
  */
 export declare function removeCurrentSessionId(config?: LocalStorage<ConfSchema>): void;
+/**
+ * Get pending device auth state for a resumable non-interactive login flow.
+ *
+ * @returns Pending device auth state, if present.
+ */
+export declare function getPendingDeviceAuth(config?: LocalStorage<ConfSchema>): PendingDeviceAuth | undefined;
+/**
+ * Stash pending device auth state for a later .
+ *
+ * @param auth - Pending device auth state.
+ */
+export declare function setPendingDeviceAuth(auth: PendingDeviceAuth, config?: LocalStorage<ConfSchema>): void;
+/**
+ * Clear pending device auth state after completion or expiry.
+ */
+export declare function clearPendingDeviceAuth(config?: LocalStorage<ConfSchema>): void;
 type CacheValueForKey<TKey extends keyof Cache> = NonNullable<Cache[TKey]>['value'];
 /**
  * Fetch from cache, or run the provided function to get the value, and cache it
packages/cli-kit/dist/private/node/constants.d.ts
@@ -7,6 +7,7 @@ export declare const environmentVariables: {
     enableCliRedirect: string;
     env: string;
     firstPartyDev: string;
+    hostedApps: string;
     noAnalytics: string;
     optOutInstrumentation: string;
     appAutomationToken: string;
packages/cli-kit/dist/private/node/session.d.ts
@@ -1,3 +1,4 @@
+import { IdentityToken, Session } from './session/schema.js';
 import { AdminSession } from '../../public/node/session.js';
 /**
  * A scope supported by the Shopify Admin API.
@@ -104,4 +105,14 @@ export interface EnsureAuthenticatedAdditionalOptions {
  * @returns An instance with the access tokens organized by application.
  */
 export declare function ensureAuthenticated(applications: OAuthApplications, _env?: NodeJS.ProcessEnv, { forceRefresh, noPrompt, forceNewSession }?: EnsureAuthenticatedAdditionalOptions): Promise<OAuthSession>;
+/**
+ * Given an identity token, exchange it for application tokens and build a complete session.
+ * Shared between the interactive login flow and the resumable non-interactive flow.
+ *
+ * @param identityToken - Identity token returned by the OAuth device code flow.
+ * @param applications - Applications to exchange access tokens for.
+ * @param existingAlias - Optional alias from a previous session to preserve if the email fetch fails.
+ * @returns A complete session with identity and application tokens.
+ */
+export declare function completeAuthFlow(identityToken: IdentityToken, applications: OAuthApplications, existingAlias?: string): Promise<Session>;
 export {};
\ No newline at end of file
packages/cli-kit/dist/public/node/session-prompt.d.ts
@@ -1,3 +1,6 @@
+interface PromptSessionSelectOptions {
+    forceNewSession?: boolean;
+}
 /**
  * Prompts the user to select from existing sessions or log in with a different account.
  *
@@ -5,6 +8,8 @@
  * - Otherwise, shows a prompt with all available sessions and the option to log in with a different account.
  *
  * @param alias - Optional alias of the account to switch to.
+ * @param options - Optional prompt behavior.
  * @returns Promise with the alias of the chosen session.
  */
-export declare function promptSessionSelect(alias?: string): Promise<string>;
\ No newline at end of file
+export declare function promptSessionSelect(alias?: string, options?: PromptSessionSelectOptions): Promise<string>;
+export {};
\ No newline at end of file
packages/cli-kit/dist/public/node/session.d.ts
@@ -33,6 +33,21 @@ interface ServiceAccountInfo {
 interface UnknownAccountInfo {
     type: 'UnknownAccount';
 }
+export type AuthStatusName = 'authenticated' | 'needs_refresh' | 'not_authenticated' | 'invalid';
+export interface AuthStatus {
+    status: AuthStatusName;
+    authenticated: boolean;
+    account?: {
+        userId: string;
+        alias?: string;
+    };
+    identityFqdn?: string;
+    expiresAt?: string;
+    agentGuidance: {
+        instruction: string;
+        nextCommand?: string;
+    };
+}
 /**
  * Type guard to check if an account is a UserAccount.
  *
@@ -47,6 +62,12 @@ export declare function isUserAccount(account: AccountInfo): account is UserAcco
  * @returns True if the account is a ServiceAccount.
  */
 export declare function isServiceAccount(account: AccountInfo): account is ServiceAccountInfo;
+/**
+ * Returns the current Shopify CLI authentication status without starting a login flow.
+ *
+ * @returns The current authentication status.
+ */
+export declare function getAuthStatus(): Promise<AuthStatus>;
 /**
  * Ensure that we have a valid session with no particular scopes.
  *
@@ -128,6 +149,40 @@ export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPla
  * @returns A promise that resolves when the logout is complete.
  */
 export declare function logout(): Promise<void>;
+export interface StartDeviceAuthLoginResult {
+    verificationUriComplete: string;
+    userCode: string;
+    expiresAt: string;
+}
+/**
+ * Start a resumable device authorization flow for non-interactive .
+ *
+ * @returns Instructions needed to authorize the device code and resume login.
+ */
+export declare function startDeviceAuthLogin(): Promise<StartDeviceAuthLoginResult>;
+export type ResumeDeviceAuthLoginResult = {
+    status: 'success';
+    alias: string;
+} | {
+    status: 'pending';
+    verificationUriComplete: string;
+    userCode: string;
+} | {
+    status: 'expired';
+    message: string;
+} | {
+    status: 'denied';
+    message: string;
+} | {
+    status: 'no_pending';
+    message: string;
+};
+/**
+ * Resume a previously started non-interactive device authorization flow.
+ *
+ * @returns The result of exchanging the stashed device code.
+ */
+export declare function resumeDeviceAuthLogin(): Promise<ResumeDeviceAuthLoginResult>;
 /**
  * Ensure that we have a valid Admin session for the given store, with access on behalf of the app.
  *
packages/cli-kit/dist/private/node/session/device-authorization.d.ts
@@ -15,9 +15,12 @@ export interface DeviceAuthorizationResponse {
  * Also returns a  used for polling the token endpoint in the next step.
  *
  * @param scopes - The scopes to request
+ * @param options - Optional settings for presenting the device authorization instructions.
  * @returns An object with the device authorization response.
  */
-export declare function requestDeviceAuthorization(scopes: string[]): Promise<DeviceAuthorizationResponse>;
+export declare function requestDeviceAuthorization(scopes: string[], { noPrompt }?: {
+    noPrompt?: boolean;
+}): Promise<DeviceAuthorizationResponse>;
 /**
  * Poll the Oauth token endpoint with the device code obtained from a DeviceAuthorizationResponse.
  * The endpoint will return  until the user completes the auth flow in the browser.
packages/cli-kit/dist/public/node/context/local.d.ts
@@ -42,6 +42,13 @@ export declare function isShopify(env?: NodeJS.ProcessEnv): Promise<boolean>;
  * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.
  */
 export declare function isUnitTest(env?: NodeJS.ProcessEnv): boolean;
+/**
+ * Returns true if the CLI is running in hosted apps mode.
+ *
+ * @param env - The environment variables from the environment of the current process.
+ * @returns True if the HOSTED_APPS environment variable is truthy.
+ */
+export declare function isHostedAppsMode(env?: NodeJS.ProcessEnv): boolean;
 /**
  * Returns true if reporting analytics is enabled.
  *

@github-actions
Copy link
Copy Markdown
Contributor

🫰✨ Thanks @gonzaloriestra! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

pnpm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260528143009

Caution

After installing, validate the version by running shopify version in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant