Skip to content

Add JSON output to GraphiQL commands - #8974

Open
gonzaloriestra wants to merge 8 commits into
mainfrom
gonzalo/graphiql-json
Open

gonzaloriestra wants to merge 8 commits into
mainfrom
gonzalo/graphiql-json

Conversation

@gonzaloriestra

@gonzaloriestra gonzaloriestra commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Agents need to discover when GraphiQL is ready and follow failures and shutdown without parsing terminal output.

Fixes https://github.com/shop/issues-develop/issues/24313
Fixes https://github.com/shop/issues-develop/issues/24316

WHAT is this pull request doing?

Adds --json to app graphiql and store graphiql. Both share typed JSONL lifecycle records (starting, ready, stopped) and schema discovery. The ready record includes the authenticated local URL, store, API context, app context, and mutation permissions. Diagnostics use stderr; fatal failures end stdout with the standard error envelope. There is no finite success result.

The shared GraphiQL session waits for the server to listen and closes active connections and aborts upstream requests on shutdown. Launcher signal delegation allows cleanup to finish before exiting. SIGINT, SIGTERM, and SIGQUIT exit with 130, 143, and 131. Existing authentication, store mutation protection, and HTTP response payloads are preserved. Browser opening remains enabled unless --no-input is supplied, independently of output format.

Updates generated help, manifests, and command documentation. Removes both commands from the JSON output exception list.

How to manually test your changes?

  1. With existing stored authentication, run pnpm shopify store graphiql --store <shop.myshopify.com> --json --no-input > /tmp/graphiql.jsonl 2> /tmp/graphiql-diagnostics.jsonl. Open the ready.url in a browser and confirm GraphiQL works. Try a mutation with the default permissions: it should remain blocked and produce a diagnostic on stderr.
  2. Press Ctrl+C. Check for a final stopped record, exit code 130, and a closed local server.
  3. In a linked app installed on the store, run pnpm shopify app graphiql --path <app-path> --store <shop.myshopify.com> --json. Confirm browser opening, the app context in ready, and shutdown. Repeat without --json to check text output.
  4. Inspect either command with --json-schema; authentication and server startup should not run.

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 (minor) and added a changeset

@github-actions github-actions Bot added the Area: @shopify/cli @shopify/cli package issues label Oct 21, 2026
@gonzaloriestra gonzaloriestra changed the title [Feature] Add JSON streaming to GraphiQL commands Add JSON output to GraphiQL commands Oct 22, 2026
@gonzaloriestra

Copy link
Copy Markdown
Contributor Author

/snapit

@github-actions

Copy link
Copy Markdown
Contributor

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

Built from 85920ecfe5901a719b1c1279f08ebc874d2f16e9. Workflow run.

Test the snapshot by installing your package globally:

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

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.

@gonzaloriestra
gonzaloriestra marked this pull request as ready for review October 23, 2026 10:20
@gonzaloriestra
gonzaloriestra requested review from a team as code owners October 23, 2026 10:20
@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

packages/cli-kit/dist/public/node/graphiql/schema.d.ts
import { type InferJsonOutputSchema } from '../json-output-schema.js';
import { zod } from '../schema.js';
/** Lifecycle records written as JSONL by the standalone GraphiQL commands. */
export declare const graphiqlJsonOutputSchema: import("../json-output-schema.js").JsonOutputSchema<zod.ZodDiscriminatedUnion<"type", [zod.ZodObject<{
    type: zod.ZodLiteral<"starting">;
    timestamp: zod.ZodString;
    storeDomain: zod.ZodString;
}, "strict", zod.ZodTypeAny, {
    type: "starting";
    timestamp: string;
    storeDomain: string;
}, {
    type: "starting";
    timestamp: string;
    storeDomain: string;
}>, zod.ZodObject<{
    type: zod.ZodLiteral<"ready">;
    timestamp: zod.ZodString;
    url: zod.ZodString;
    storeDomain: zod.ZodString;
    api: zod.ZodLiteral<"admin">;
    apiVersion: zod.ZodNullable<zod.ZodString>;
    mutationsAllowed: zod.ZodBoolean;
    app: zod.ZodNullable<zod.ZodObject<{
        name: zod.ZodString;
        url: zod.ZodString;
    }, "strict", zod.ZodTypeAny, {
        name: string;
        url: string;
    }, {
        name: string;
        url: string;
    }>>;
}, "strict", zod.ZodTypeAny, {
    type: "ready";
    url: string;
    timestamp: string;
    app: {
        name: string;
        url: string;
    } | null;
    api: "admin";
    storeDomain: string;
    apiVersion: string | null;
    mutationsAllowed: boolean;
}, {
    type: "ready";
    url: string;
    timestamp: string;
    app: {
        name: string;
        url: string;
    } | null;
    api: "admin";
    storeDomain: string;
    apiVersion: string | null;
    mutationsAllowed: boolean;
}>, zod.ZodObject<{
    type: zod.ZodLiteral<"stopped">;
    timestamp: zod.ZodString;
    reason: zod.ZodEnum<["cancelled", "sigint", "sigterm", "sigquit"]>;
}, "strict", zod.ZodTypeAny, {
    type: "stopped";
    timestamp: string;
    reason: "cancelled" | "sigint" | "sigterm" | "sigquit";
}, {
    type: "stopped";
    timestamp: string;
    reason: "cancelled" | "sigint" | "sigterm" | "sigquit";
}>]>>;
type WithoutTimestamp<T> = T extends unknown ? Omit<T, 'timestamp'> : never;
type GraphiQLRecord = InferJsonOutputSchema<typeof graphiqlJsonOutputSchema>;
export type GraphiQLRecordInput = WithoutTimestamp<GraphiQLRecord>;
export {};

Existing type declarations

packages/cli-kit/dist/public/node/graphiql/server.d.ts
@@ -65,6 +65,10 @@ export interface SetupGraphiQLServerOptions {
      * interactive UI.
      */
     protectMutations?: boolean;
+    /** Called for request failures that leave the server available for subsequent requests. */
+    onRequestError?: (message: string) => void;
+    /** Routes diagnostics through command events and leaves readiness output to the session. */
+    json?: boolean;
 }
 export declare const MUTATIONS_BLOCKED_MESSAGE = "Mutations are disabled. Re-run with --allow-mutations to enable mutations.";
 /**
packages/cli-kit/dist/public/node/graphiql/session.d.ts
@@ -22,6 +22,7 @@ export interface RunGraphiQLSessionOptions {
     additionalReadyMessages?: OutputMessage[];
     abortSignal?: AbortSignal;
     stdout?: Writable;
+    outputFormat?: 'text' | 'json';
 }
 /**
  * Generates a random key suitable for authenticating a single local GraphiQL session.

This branch has not been deployed

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

Labels

Area: @shopify/cli @shopify/cli package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant