Skip to content

Add JSON schema for theme info - #8525

Open
dmerand wants to merge 6 commits into
mainfrom
donald/theme-info-json-schema
Open

dmerand wants to merge 6 commits into
mainfrom
donald/theme-info-json-schema

Conversation

@dmerand

@dmerand dmerand commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

theme info --json has two established result shapes, but neither is discoverable as a command contract.

Related to shop/issues-develop#23691

WHAT is this pull request doing?

  • Add a schema for the existing theme and environment JSON results.
  • Preserve both JSON shapes, text output, and per-environment emission.
  • Move JSON/text selection to the command result boundary.
  • Record opening and closing analytics timings in both text and JSON modes.

Normal output remains human-readable sections:

Theme Configuration
Store                 my-shop.myshopify.com
Development Theme ID  Not set

Tooling and System
Shopify CLI  3.91.0
OS           darwin-arm64
Shell        /bin/zsh
Node version v24.15.0

The matching JSON output remains:

{
  "store": "my-shop.myshopify.com",
  "development_theme_id": null,
  "cli_version": "3.91.0",
  "os": "darwin-arm64",
  "shell": "/bin/zsh",
  "node_version": "v24.15.0"
}

A multi-environment invocation continues to emit one existing JSON document per environment. This PR does not add a wrapper or change that public behavior.

Validate non-interactive requirements after loading each environment, so configured theme IDs work while conditional safety flags remain required. Environment notices use JSON diagnostics in JSON mode. Unsupported multiple environments and a global --path now fail with a nonzero exit code; confirmation prompts use the stable command ID.

How to manually test your changes?

shopify theme info
shopify theme info --json
shopify theme info --json-schema
shopify theme info --environment development --environment staging --json

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
  • A single changeset for all theme migrations is added in the last PR, #8682.

@github-actions github-actions Bot added the Area: @shopify/theme @shopify/theme package issues label Sep 11, 2026
@dmerand
dmerand requested review from a team September 11, 2026 01:53
@dmerand
dmerand force-pushed the donald/theme-info-json-schema branch from cf6bd6d to 42bc978 Compare September 11, 2026 14:24
@gonzaloriestra

Copy link
Copy Markdown
Contributor

/snapit

@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-20260915114646

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.

Comment thread packages/theme/src/cli/commands/theme/info.ts
Comment thread packages/theme/src/cli/commands/theme/info.ts
Base automatically changed from gonzalo/json-schema-flag to gonzalo/json-support-by-default September 16, 2026 11:13
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from f46d908 to 0c95979 Compare September 16, 2026 11:21
@gonzaloriestra
gonzaloriestra changed the base branch from gonzalo/json-support-by-default to main September 16, 2026 11:21
@github-actions github-actions Bot added Area: @shopify/cli @shopify/cli package issues Area: @shopify/theme @shopify/theme package issues and removed Area: @shopify/theme @shopify/theme package issues Area: @shopify/cli @shopify/cli package issues labels Sep 16, 2026
@gonzaloriestra
gonzaloriestra added this pull request to stack #8644 September 24, 2026 09:19
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from 77bfbfd to d18e392 Compare September 24, 2026 10:04
@gonzaloriestra
gonzaloriestra removed this pull request from stack #8644 September 24, 2026 10:04
@gonzaloriestra
gonzaloriestra added this pull request to stack #8655 September 24, 2026 10:05
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from d18e392 to 6d61a3e Compare September 24, 2026 10:25
@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/theme @shopify/theme package issues labels Sep 24, 2026

static descriptionWithMarkdown = `Displays information about your theme environment, including your current store. Can also retrieve information about a specific theme.

Use \`--json\` for machine-readable output.`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need this with the help and new instructions from the skill, I'll remove it.

@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from 6d61a3e to cb7a4db Compare September 24, 2026 11:56
@gonzaloriestra
gonzaloriestra marked this pull request as ready for review September 24, 2026 14:13
@gonzaloriestra
gonzaloriestra added this pull request to stack #8673 September 25, 2026 12:29
@github-actions github-actions Bot added Area: @shopify/app @shopify/app package issues and removed no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. labels Sep 25, 2026
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from 2eabb1e to ba2e4d3 Compare September 28, 2026 08:20
@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/app @shopify/app package issues labels Sep 28, 2026
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch 3 times, most recently from a70adad to eea5b12 Compare September 28, 2026 11:51
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from eea5b12 to 60623ee Compare September 29, 2026 10:28
Comment thread packages/theme/src/cli/commands/theme/info.ts Outdated
Comment thread packages/theme/src/cli/commands/theme/info.test.ts Outdated
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch 2 times, most recently from f13bb3d to f08da6c Compare September 29, 2026 13:44
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from f08da6c to 481ed4c Compare September 29, 2026 14:18
Base automatically changed from gonzalo/json-render-tasks to main September 29, 2026 14:40
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from 481ed4c to 6c8372f Compare September 29, 2026 14:40
emitCommandEvent({
type: 'diagnostic',
level: 'info',
message: `Using applicable flags from ${environmentName} environment:\n${items.join('\n')}`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: let's redact store-password before emitting these diagnostics too. The reporter only masks the exact password key, so an environment's storefront password is included in full in the JSON diagnostic message. theme profile --environment preview --json supports this field. The text banner already had this redaction gap, but this branch now sends the secret through the structured event channel as well. Redact both credential fields before building items, and extend the diagnostic test to check that the full storefront password never appears in emitted events.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both credential fields are now masked


protected validateNonTTYFlags(flags: FlagOutput): void {
// Multiple environments must be validated after their configured flags are loaded.
const command = this.constructor as unknown as {multiEnvironmentsFlags?: RequiredFlags}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: let's use an assertion-free property check instead of as unknown as {multiEnvironmentsFlags?: RequiredFlags} here. This hook only needs to know whether the constructor defines the metadata. The double assertion bypasses compiler checks and isn't needed:

const command = this.constructor
if (
  'multiEnvironmentsFlags' in command &&
  command.multiEnvironmentsFlags !== undefined &&
  Array.isArray(flags.environment) &&
  flags.environment.length > 1
) {
  return
}

Keep the undefined-versus-null distinction: own-runner commands without this metadata must retain parse-time validation. Don't add a default of null to the base class.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the double assertion with the suggested property check. The undefined-versus-null distinction is preserved.


await run(['--theme', '123', ...(json ? ['--json'] : [])])

expect(vi.mocked(recordTiming).mock.calls).toEqual([['theme-command:info'], ['theme-command:info']])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: let's assert that these timings bracket the work, rather than only checking two identical calls. Moving the closing timing immediately after the opening timing still passes this test in both modes, even though the duration excludes fetching and presenting the result. Check that only the opening timing exists while the fetch is pending, then that the closing timing is recorded after presentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both modes now verify that only the opening timing exists while fetching is pending, and that presentation happens before the closing timing

],
}),
)
await expect(command.run()).rejects.toThrow("Can't use `--path` flag with multiple environments.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: let's keep checking the branch-specific recovery advice as well as the rejection. Both modified tests now assert the same heading, so they still pass if the missing-file case tells users to edit a configuration file that does not exist. Assert the AbortError guidance for each case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both cases now assert the AbortError and their specific recovery advice, using real temporary files in theme-command-environments.test.ts

Assisted-By: devx/9dd3b67e-58e9-4a01-a721-43265d02ccd2
Assisted-By: devx/9dd3b67e-58e9-4a01-a721-43265d02ccd2
Assisted-By: devx/b173c0b4-2d65-4396-a5eb-d3c4d4c3a4ff
Assisted-By: devx/0033c079-2574-4c3b-a8f1-d9a752834d90
Assisted-By: devx/1fb42754-a68b-4733-9ea3-74521b5da069
Assisted-By: devx/8b520d2e-bc34-4a3d-b5fa-748b2fff362e
@gonzaloriestra
gonzaloriestra force-pushed the donald/theme-info-json-schema branch from 6c8372f to 078784e Compare October 1, 2026 08:52
@github-actions

github-actions Bot commented Oct 1, 2026

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/node/base-command.d.ts
@@ -35,6 +35,7 @@ declare abstract class BaseCommand extends Command {
         argv: string[];
     }>;
     protected environmentsFilename(): string | undefined;
+    protected validateNonTTYFlags(flags: FlagOutput): void;
     protected failMissingNonTTYFlags(flags: FlagOutput, requiredFlags: string[]): void;
     private failMissingNonTTYFlagRequirements;
     private applicableNonTTYFlagRequirements;

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

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.

5 participants