Skip to content

Document CLI design guidance for contributors - #8745

Open
dmerand wants to merge 2 commits into
mainfrom
donald/designing-for-cli-20261002
Open

dmerand wants to merge 2 commits into
mainfrom
donald/designing-for-cli-20261002

Conversation

@dmerand

@dmerand dmerand commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Contributors and coding agents need CLI design guidance that does not depend on internal documentation or design files. Shared guidance helps new commands and flows stay consistent with the rest of Shopify CLI.

WHAT is this pull request doing?

Adapt the internal CLI design article into public contributor guidance and route coding agents to its design, syntax, and UI rules. Keep command outcomes and flows separate from the existing syntax and UI content rules. Replace private references and screenshots with standalone text, and use the existing JSON, error, and UI contracts.

Preserve supported command defaults and accepted option values. This changes contributor docs, not CLI behavior, so no changeset is needed.

How to manually test your changes?

git show HEAD:AGENTS.md # Follow the design, command, and UI routes.
git show HEAD:docs/cli/designing-for-cli.md
git show HEAD:docs/cli-kit/command-guidelines.md # Check Boolean defaults and accepted-value qualifications.
git show HEAD:docs/cli-kit/ui-kit/guidelines.md # Compare active and completed states.

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

@github-actions github-actions Bot added the no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. label Oct 2, 2026
@dmerand
dmerand requested a balanced review from Copilot October 2, 2026 20:32

Copilot AI left a comment

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.

Copilot review overview

🟢 Approval recommended

The documentation is consistent with existing CLI contracts and its new internal links resolve correctly.

Review effort: Balanced
Findings: None

What changed in this PR

Adds public contributor guidance for designing consistent Shopify CLI commands and terminal experiences.

Changes:

  • Adds CLI outcome, lifetime, automation, and progress guidance.
  • Expands command syntax, flag, prompt, banner, and logging conventions.
  • Links the new guidance from the contributor documentation index.
File Description
docs/​README.md Links the new design guide.
docs/​cli/​designing-for-cli.md Introduces CLI design principles.
docs/​cli-kit/​ui-kit/​guidelines.md Expands content and terminal UI guidance.
docs/​cli-kit/​command-guidelines.md Clarifies command structure, flags, options, and help text.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

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.

Copilot review overview

🟢 Approval recommended

The documentation is internally consistent, preserves existing contracts, and its new local links resolve correctly.

Review effort: Balanced
Findings: None

@dmerand
dmerand marked this pull request as ready for review October 2, 2026 21:48
@dmerand
dmerand requested a review from a team as a code owner October 2, 2026 21:48

Use UI Kit's semantic tokens for commands, user input, and other styled text. Use its standard banner types rather than assigning your own colors. The [token system](./readme.md#the-token-system) keeps these meanings consistent without requiring commands to manage a palette.

Developers can customize their terminal colors. A terminal mockup can start with a 16-color palette, but do not depend on exact hues. Keep the standard associations of red with errors, yellow with warnings, and green with success. Always communicate the meaning through text as well as color.

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 don't think this is worded strongly enough. The point is that the CLI output should be completely understandable in no color mode, both for accessibility reasons and for environments like CI systems where color or other text decorations like bold/italic/underline may not be supported.


Developers can customize their terminal colors. A terminal mockup can start with a 16-color palette, but do not depend on exact hues. Keep the standard associations of red with errors, yellow with warnings, and green with success. Always communicate the meaning through text as well as color.

Use emojis sparingly to draw attention or clarify meaning, not as decoration. Keep neutral output quiet. An active indicator, such as UI Kit's animated progress bar, should distinguish running work from completed or failed work.

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 believe our policy is not to use emojis at all, because not all terminals and environment support them. We do support a limited set of symbols through the figures package.


## Use color and emphasis with purpose

Use grayscale text for neutral information. Use brighter foreground text for emphasis. Reserve color for semantic meaning, such as success, warnings, and errors, or to connect related log entries, such as entries from the same extension.

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 don't think we actually use grayscale text for neutral information - we could go in that direction, but I don't think it's a standard today. Instead, usually it's used as an accent color that avoids the impression of highlighting, e.g. as the row title column in a table.

Image

| --- | --- |
| Text entry | A value such as an app name or version name. Offer an editable default when it helps the developer continue. |
| Single select | A list of choices. Group related choices when that makes the list easier to scan. |
| Confirmation | A high-risk choice. Use sparingly, such as before deploying an app version that removes an extension. |

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.

Technically Dangerous Confirmation - also, I would define it as being for one-way doors, such as irretrievably deleting information (which is why removing an extension is dangerous - because when the app is deployed, there is the potential for information to be lost).

| Single select | A list of choices. Group related choices when that makes the list easier to scan. |
| Confirmation | A high-risk choice. Use sparingly, such as before deploying an app version that removes an extension. |

An editable default lets the developer press Enter to accept a suggested name or type their own. Show the choice rather than making an unexplained inference. See the [prompt APIs](./readme.md#prompts) for supported defaults and grouping.

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.

This isn't true for text prompts - the default is blank, and the user presses Tab to accept the default.

- A text prompt with a noun and colon: "App name:"
- A selection prompt followed by a colon: "Select extension type:"

Do not require an interactive prompt for automated use. Follow the [JSON output contracts](../../cli/json-output.md#preserve-compatibility) for the independent roles of output format and interactivity.

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'd phrase this a bit differently, as anything that potentially requires a prompts must be specifiable via a flag for non-interactive cases.

| package manager | CLI (always Shopify) | Topic | Command | Argument | Flags (with or without options) |
| :------------- | :------------- | :------------- | :------------- |:------------- |:------------- |
| yarn | Shopify | app | generate | extension | --type checkout_ui
A global installation is available across projects. A local installation belongs to one project or directory. For a project-local installation, use that project's package-manager invocation. For example, a project with a local Shopify CLI can use:

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.

We can probably trim all this a bunch, given we're fully into global these days.

### Topics

## Topics
Create a topic only when you add an entirely new domain to the CLI. Get maintainer input before you add one. Domain topics include `app` and `theme`. Hydrogen commands are supplied by a separate plugin; see the [architecture guide](../cli/architecture.md).

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.

and store and organization now!

| ✅ | Do: | pnpm add <package> --ignore-workspace-root-check | This flag is long, but it accurately describes the choice the developer is making. |
| :------------- | :------------- | :------------- | :------------- |
| ❌ | Don't: | rsync --owner | Because it’s unnecessarily terse, it’s ambiguous whether this flag means “preserve the current owner” or “assign ownership”.|
Do not shorten them to `--sync` and `--reload`: those names remove context. They are not supported alternatives for this command.

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.

This is phrased as a concrete instruction instead of the real intent, which is an example.

### Options

By default, two-word options are formatted with hyphens but should also accept underscores.
A flag can accept specific values, called options. Accept a space or an equals sign between a flag and its value:

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.

Accept a space or an equals sign between a flag and its value isn't the responsibility of a maintainer, it's part of oclif default behavior.

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.

3 participants