Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Read the guides that apply to your task.

- [Docs index](docs/README.md): find related guides and the reasons behind past decisions.
- [Architecture](docs/cli/architecture.md): choose the right package for new or moved code.
- [Designing for CLI](docs/cli/designing-for-cli.md): design command outcomes, lifetimes, and long-running workflows.
- [Conventions](docs/cli/conventions.md): follow shared patterns for modules, state, resource cleanup, and file IO.
- [Cross-OS compatibility](docs/cli/cross-os-compatibility.md): avoid OS-specific failures when working with paths, processes, and dependencies.
- [Debugging](docs/cli/debugging.md): investigate failures with the debugger and check diagnostics for credential leaks.
Expand All @@ -78,14 +79,14 @@ Read the guides that apply to your task.

### CLI kit

- [Command guidelines](docs/cli-kit/command-guidelines.md): design commands and flags with consistent structure, defaults, and dependencies.
- [Command guidelines](docs/cli-kit/command-guidelines.md): design commands and flags with consistent structure, defaults, dependencies, accepted values, and help text.
- [Error handling](docs/cli/error_handling.md): choose error types, report failures, and retry only known recoverable conditions.
- [Command reference](packages/cli/README.md): check documented command usage, flags, and examples.

### UI kit

- [Contributing to UI Kit](docs/cli-kit/ui-kit/contributing.md): follow component design and testing patterns when changing UI Kit.
- [Content guidelines](docs/cli-kit/ui-kit/guidelines.md): keep prompts, progress messages, and error text consistent.
- [Content and UI guidelines](docs/cli-kit/ui-kit/guidelines.md): keep prompts, banners, progress, and logs consistent, and use semantic styling.
- [Using UI Kit](docs/cli-kit/ui-kit/readme.md): use existing prompt and output APIs for consistent terminal UI.

Follow the check requirements of the active automation task.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The list below contains valuable resources for people interested in contributing

* [Get started](./cli/get-started.md)
* [Architecture](./cli/architecture.md)
* [Designing for CLI](./cli/designing-for-cli.md)
* [Conventions](./cli/conventions.md)
* [JSON output contracts](./cli/json-output.md)
* [Performance](./cli/performance.md)
Expand Down
73 changes: 42 additions & 31 deletions docs/cli-kit/command-guidelines.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,72 @@
# Command guidelines

## General command structure
Use [Designing for CLI](../cli/designing-for-cli.md) to choose the command's outcome and flow. These guidelines cover its public syntax and help. Check the [reserved command and flag names](../cli/naming-conventions.md) before you add a name.

When the CLI is installed via an app package, then commands are structured like this:
## General command structure

| package manager | CLI (always Shopify) | Topic | Command | Argument | Flags (with or without options) |
| :------------- | :------------- | :------------- | :------------- |:------------- |:------------- |
| yarn | Shopify | app | generate | extension | --type checkout_ui
Commands move from a broad domain to a specific action:

When the CLI is installed globally, then commands are structured like this:
| CLI | Topic | Command | Subcommand | Flag and value |
| --- | --- | --- | --- | --- |
| `shopify` | `app` | `deploy` | | |
| `shopify` | `app` | `generate` | `extension` | |
| `shopify` | `theme` | `dev` | | `--live-reload full-page` |

|CLI (always Shopify) | Topic | Command | Argument | Flags (with or without options) |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| shopify | hydrogen | add | eslint | _no flag_ |
If a verb applies to more than one object, put the verb before the object: `shopify app generate extension`. Here, `extension` is a subcommand, not a positional argument. Add further subcommands only when they are necessary for clarity. Separate command words with spaces, not hyphens.

Generic commands that cross domains don't have topics. Examples include help, version, upgrade, and logs:
Examples use a global installation of Shopify CLI.

| package manager | CLI (always Shopify) | Topic | Command | Argument | Flags (with or without options) |
| :------------- | :------------- | :------------- | :------------- | :------------- | :------------- |
| npm run | shopify | _no topic_ | help | extension | _no flag_ |
### 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`, `theme`, `store`, and `organization`. Hydrogen commands are supplied by a separate plugin; see the [architecture guide](../cli/architecture.md).

A new topic should only be created when an entirely new domain is being added to the CLI. Today, topics include adds, themes, and hydrogen.
Commands that apply across domains do not need a domain topic. Examples include `shopify help`, `shopify version`, and `shopify upgrade`.

## Flags

Any given flag needs to be consistent not only within a topic, but also across the main CLI package. A flag always means the same thing, and it can be pre-set to a specific value.
Use flags, rather than positional arguments, to modify command behavior. Named flags make the choice explicit, do not depend on argument order, and are easier to extend without ambiguity.

A flag must mean the same thing within a topic and across the main CLI package. It can have a pre-set value. Prefer clarity over brevity, especially in scripts and CI environments where a descriptive name documents the developer's intent.

For example, these names explain both choices:

Flags should be semantically meaningful. When in doubt, optimize for clarity, not brevity. This is particularly important in non-interactive or CI environments, where a command is likely to be a write-once, run-many situation. Verbose flags are better for self-documention.
```sh
shopify theme dev --theme-editor-sync --live-reload full-page
```

| ✅ | 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”.|
Shorter names, such as `--sync` or `--reload`, would not say what is synced or reloaded.

For changed dependent or defaulted flags, test omitted, explicit, default, valid, and invalid combinations through actual command parsing. A default value does not prove explicit presence; choose dependency declarations according to the intended behavior, not an “always `dependsOn`” rule.

Command result, error, and output changes follow the existing [JSON contracts](../cli/json-output.md) and [error handling](../cli/error_handling.md).

## Aliases / shortcuts for flags
### Aliases / shortcuts for flags

As a general rule, don't create shortcuts for flags. Create single-letter short-form flag aliases only if the flag is frequently or repetitively used in day-to-day interactive development work.
Use a full name with two hyphens, such as `--store`. As a general rule, do not add a short alias. Add a single-letter alias only for a flag used frequently or repeatedly in daily interactive development.

Shortcuts can leave off the topic keyspace of the command.
Short aliases use one hyphen and can omit context already supplied by the topic. Preserve the reserved meanings of common aliases, such as `-s` for `--store`, and existing topic-specific aliases, such as `-t` for `--theme` in theme commands.

## Booleans
### Booleans

A boolean flag takes the options of either true ('--OPTION') or false ('--no-OPTION'). In general, make the true option the default. That is, `--OPTION` should be the same as not passing the flag at all. Ex: '--tunnel' / '--no-tunnel'.
A feature toggle turns a behavior on or off, such as `--watch` and `--no-watch` in `shopify app function replay`. Give a new feature toggle both forms: `--OPTION` enables the behavior and `--no-OPTION` disables it. In general, make the enabled behavior the default when it is safe and useful for most developers. This does not apply to safety controls, destructive actions, output modes such as `--json`, or other documented opt-in modes. For example, `shopify theme dev --allow-live` must remain an explicit choice.

## Options
Preserve each existing command's documented defaults and supported flag forms. Do not assume that every boolean automatically supports a `--no-` form.

A flag can accept specific values (called “options”). The CLI should accept either a space or an equals sign:
* generate extension --type checkout_ui
* generate extension --type=checkout_ui
### Options

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

```sh
shopify theme dev --live-reload full-page
shopify theme dev --live-reload=full-page
```

For new multi-word option values, use hyphens by default and accept underscore aliases where appropriate. Define and document those aliases explicitly. Existing commands' accepted-value contracts remain authoritative: do not assume an underscore spelling works for every existing option.

Use a space between the flag and value in documentation. If the value contains spaces, use an equals sign and quote the value so the shell passes it as one value.

## Help

Every command should have a corresponding description in the help directory. The help description should be a sentence fragment in the third-person singular, as if it's a sentence that starts with "This command...' For example: "Adds an extension to your app project" is the description for the command "shopify hydrogen info".
Give every command, flag, and accepted option a description in command help. For a command, write both the summary and the description as sentence fragments in the third-person singular, as if they start with "This command...". Help shows both. For example, describe `shopify app generate extension` as "Generates a new app extension."

Explain what the command does, not its internal implementation. Keep help, accepted values, and examples consistent with the command definition. Follow the [JSON output contracts](../cli/json-output.md) for result schema documentation.
94 changes: 75 additions & 19 deletions docs/cli-kit/ui-kit/guidelines.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,78 @@
# Content guidelines
# Content and UI guidelines

It's important to be consistent in how we display content to users of the CLI.
These guidelines should guide you when choosing your style of communication with the users.
Use consistent content and visual patterns so developers can focus on their work. Use the [CLI UI Kit](./readme.md) for rendering and [Designing for CLI](../../cli/designing-for-cli.md) for command and flow decisions.

## General content guidelines
- Use contractions (ex: can't instead of cannot). It's the easiest way to sound human.
- Use “we” to refer to Shopify. (This "we" framing acts as a trust signal. In the platform context, Shopify and the developer are building value together. We're not slippery; we're not hiding.)

## Prompting user inputs with selection and text prompts:
- A full-sentence question (“Have you installed your app on your dev store?”)
- A text prompt with simple noun followed by a colon (“App name:”)
- A list prompt followed by a colon: (“Select extension type:”)

## Communicating processes with dynamic checkmarks:
- Progress indicators should take this passive voice formula: “Dependencies installed”; “App initialized”; “App deployed”. In other words: 'noun' 'verb' (past participle).

## Content in banners:
- Each of the banner elements can support robust messaging with a next steps section and a reference section with links. The prompt components can also be customized with, for example, headings to group selection options.
- For info banners: Use present perfect tense to describe a significant display (“The REST API has been deprecated”).
- For error messages: Use the present tense to describe what’s happening in the error message context (“Can’t connect to the Storefront API”)
- More examples in the CLI example page. Run <PACKAGEMANAGER> shopify kitchen-sink all

- Use contractions, such as "can't" instead of "cannot", to sound human.
- Use "we" to refer to Shopify. Make it clear what Shopify does and what the developer controls.
- State what is happening and what the developer can do next. Do not hide consequential decisions behind automatic guesses.

## Use color and emphasis with purpose

Use the default text style for most output. Use the `subdued` token as a gray accent that does not suggest highlighting, such as the row-title column of a table. Reserve color for semantic meaning, such as success, warnings, and errors, or to connect related log entries, such as entries from the same extension.

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.

Output must be completely understandable without color or text decoration. This supports accessibility, `--no-color`, and environments such as CI systems where color, bold, italic, or underline may not be available. Developers can also customize their terminal colors, so do not depend on exact hues. Keep the standard associations of red with errors, yellow with warnings, and green with success.

Do not use emojis: not every terminal and environment can display them. Use the limited set of symbols that `@shopify/cli-kit/node/figures` provides. Keep neutral output quiet. An active indicator, such as UI Kit's animated progress bar, should distinguish running work from completed or failed work.

## Prompting user inputs with selection and text prompts

Use prompts to request information during an interactive session:

| Prompt | Use |
| --- | --- |
| Text entry | A value such as an app name or version name. Offer a 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 yes-or-no choice before the command continues, such as "Release a new version of this app?" |
| Dangerous confirmation | A one-way door, such as irretrievably deleting information. For example, deploying an app version that removes an extension can permanently delete that extension's data. The developer types a confirmation value. Use sparingly. |

A text prompt shows its default as placeholder text in a blank input. The developer presses Tab to insert the default and edit it, presses Enter to accept it, or types another value. Show the choice rather than making an unexplained inference. See the [prompt APIs](./readme.md#prompts) for supported defaults and grouping.

Use one of these forms:

- An explicit question: "Which existing app is this for?" or "Have you installed your app on your dev store?"
- A short question in the context of the flow: "Release a new version of this app?"
- A text or selection prompt with a noun and colon: "App name:"

Anything that can require a prompt must also be specifiable with a flag, so non-interactive runs, such as CI and scripts, can supply it. Follow the [JSON output contracts](../../cli/json-output.md#conventions-and-changesets) for the independent roles of `--json` and `--no-input`.

## Communicating active and completed work

For an active progress indicator, describe the work with an *-ing* form, such as "Template downloading" or "App initializing". Put this text with the indicator so the developer knows what is running.

For completed work shown with dynamic checkmarks, use a noun and past participle: "Dependencies installed", "App initialized", or "App deployed". Do not label an active operation as complete.

Use the [async task APIs](./readme.md#async-tasks) for consistent progress rendering. If work fails part way through, identify what succeeded and what failed, and give a recovery step when one is known.

## Content in banners

Use a banner for information that is usually longer than one line. Choose a success, warning, info, or error banner to match the state. A banner can contain:

- An optional heading that describes the problem or success state.
- Body text with the details the developer needs.
- Optional **Next steps**: a bulleted list of actions, including specific commands where useful.
- Optional **References**: a list of relevant developer resources.

See the [static output APIs](./readme.md#static-output) for banner fields. Keep optional sections out when they add no information.

For info banners, use present perfect tense for a significant change: "The REST API has been deprecated".

For error headings, use present tense: "Can't connect to the Storefront API". If the recovery is known, give explicit next steps. For example, "View the complete error log at `path/to/file`". Use the Next steps section when there are several actions. Follow the [error handling principles](../../cli/error_handling.md) for the error type and recovery data.

## Logs

Logs describe work as it happens. Use present tense for active work, such as "Building GraphQL types…", and past tense for a completed state, such as "order-status successfully built".

Keep neutral events that do not require action in the default text style. Reserve semantic color for errors, warnings, and successes. Stable labels and consistent per-extension colors can connect related entries across a development session. Keep the labels understandable without color.

Make an error in development-session logs easy to scan: use a heading with an error symbol, then a second line with the problem and the developer's next action. A tree marker can connect the two lines. For example:

```text
✖ Error
└ Can't connect to the Storefront API. Check your connection and try again.
```

This is an illustrative layout, not the exact output of a command. For finite machine-readable output, keep diagnostics and progress separate from the final result as specified by the [JSON output contracts](../../cli/json-output.md).
Loading
Loading