Repository navigation
Conversation
There was a problem hiding this comment.
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.
|
|
||
| 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
| | --- | --- | | ||
| | 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. | |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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). |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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.

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?
Checklist
patchfor bug fixes ·minorfor new features ·majorfor breaking changes) and added a changeset withpnpm changeset add