Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .agents/automated-tasks/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Every branch you create MUST start with `performance-` (e.g. `performance-memoiz
- Do exactly ONE thing per PR.
- Run `pnpm lint`, `pnpm knip`, `pnpm type-check`, and `pnpm test` (or the project's equivalents) before opening the PR.
- Avoid adding comments to the code, unless they are important
- Document expected performance impact in the PR body and/or code comments.
- Document expected performance impact and reproducible measurements in PR evidence, not code comments.
- When in doubt, do NOT ask for clarification — pick the best reasonable option and open the PR.

🚫 **Never do:**
Expand Down Expand Up @@ -106,7 +106,7 @@ Every branch you create MUST start with `performance-` (e.g. `performance-memoiz
- Add comments explaining WHY the optimization is correct and safe.
- Preserve existing functionality exactly.
- Consider edge cases.
- Add benchmark/perf metrics in comments where useful.
- Put benchmark/perf metrics and reproduction details in PR evidence, not code comments.
- Do NOT add a changeset file.
- Do NOT add any extra markdown files.

Expand Down
2 changes: 1 addition & 1 deletion .agents/automated-tasks/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Every branch you create MUST start with `security-` (e.g. `security-sanitize-inp
- Replace a weak hash or `Math.random()` with a secure primitive
- Add an authorization check to an endpoint or command
- Replace string concatenation with a parameterized query / safe builder
- Resolve and normalize a path before using it (defeats `..` traversal)
- Verify restricted paths stay within the allowed root using established helpers and the operation's ancestor/symlink policy; normalization alone does not prove containment
- Remove a hardcoded secret and load it from env/config
- Add a size or length cap to prevent DoS
- Tighten an overly permissive default (CORS, file mode, scope)
Expand Down
51 changes: 29 additions & 22 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Agent Instructions

As a Principal Developer, the highest ranking engineer at our company, you are tasked with creating clear, readable code in TypeScript. You use the latest version of all of these technologies, and follow their best practices and conventions.
Contribute clear, readable TypeScript that follows repository conventions. Use versions supported by the package engines, lockfile, and workflows, not the latest versions by default.

Match your planning to the complexity of the task. For anything beyond a small or obvious change, outline your intended approach before writing code — which files you'll touch and the shape of the solution — so it can be checked before you commit to an implementation. Keep this to a few sentences or bullets. For trivial changes, skip straight to the implementation.

You carefully provide accurate, factual, thoughtful answers, and are a genius at reasoning; but you always admit when you don't know the answer.
Give accurate, factual answers. State uncertainty and material trade-offs; do not guess.

Remember the following important mindset when providing code, in the following order:
- Adherence to conventions and patterns in the rest of the codebase
Expand All @@ -21,7 +21,7 @@ Adhere to the following guidelines in your code:
- Fully implement all requested functionality
- Leave no TODOs, FIXMEs, placeholders or missing pieces.
- Always consider the experience of a developer who will be reading your code.
- Use comments to explain why you are doing something in a certain way, if it is not obvious. If unsure, leave a comment.
- Use comments for durable, non-obvious reasons or invariants, not code narration, old-implementation history, PR explanations, or fragile benchmark figures. Preserve public JSDoc.
- Employ descriptive, human-readable variable and function/const names.
- Prefer writing in a functional style, producing pure functions that do not cause side effects.
- The codebase is strictly linted; follow the existing code style to ensure consistency.
Expand All @@ -40,7 +40,7 @@ Adhere to the following guidelines in your code:
- Write a concise description, explaining the problem and the high-level approach. Include implementation details only when they help reviewers understand a decision or tradeoff. Avoid repeating what is clear from the diff. Example for the WHAT section: "Refresh expired credentials before retrying the requests, so users can continue without signing in again".
- Remove empty sections and hidden comments.
- Do not mark checklist items as completed (except the changelog one if added).
- In "How to test your changes?" only include CLI commands to test locally, do not add commands to run tests or other checks.
- In "How to manually test your changes?", give useful local reviewer steps or CLI commands, not commands to run tests or other checks. This does not require live-state-changing commands.

## Changesets

Expand All @@ -56,29 +56,36 @@ If the change is not ready to be public, do not add a changeset.

## Further reading

Read the guides that apply to your task.

### CLI

- [docs/README.md](docs/README.md)
- [docs/cli/architecture.md](docs/cli/architecture.md)
- [docs/cli/conventions.md](docs/cli/conventions.md)
- [docs/cli/cross-os-compatibility.md](docs/cli/cross-os-compatibility.md)
- [docs/cli/debugging.md](docs/cli/debugging.md)
- [docs/cli/eslint-rules.md](docs/cli/eslint-rules.md)
- [docs/cli/faq.md](docs/cli/faq.md)
- [docs/cli/get-started.md](docs/cli/get-started.md)
- [docs/cli/naming-conventions.md](docs/cli/naming-conventions.md)
- [docs/cli/performance.md](docs/cli/performance.md)
- [docs/cli/testing-strategy.md](docs/cli/testing-strategy.md)
- [docs/cli/troubleshooting.md](docs/cli/troubleshooting.md)
- [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.
- [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.
- [ESLint rules](docs/cli/eslint-rules.md): understand local lint rules for command flags and environment variables.
- [FAQ](docs/cli/faq.md): understand the choice of TOML for configuration files.
- [Get started](docs/cli/get-started.md): set up the repository and run the CLI against a local project.
- [Naming conventions](docs/cli/naming-conventions.md): use reserved command names, flags, and short forms consistently.
- [Performance](docs/cli/performance.md): measure performance changes and control startup cost and concurrent work.
- [Testing strategy](docs/cli/testing-strategy.md): write tests that detect regressions and choose the appropriate test suite.
- [Troubleshooting](docs/cli/troubleshooting.md): resolve known Vitest mocking problems.
- [Contributing](CONTRIBUTING.md): check changeset, versioning, and deprecation rules before changing public behavior.
- [JSON output contracts](docs/cli/json-output.md): check result and error contracts before changing `--json` output.
- [CLI pre-submit CI](.agents/skills/cli-pre-submit-ci/SKILL.md): choose local checks and generated-file updates that match your change.

### CLI kit

- [docs/cli-kit/command-guidelines.md](docs/cli-kit/command-guidelines.md)
- [docs/cli-kit/errors.md](docs/cli-kit/errors.md)
- [packages/cli/README.md](packages/cli/README.md)
- [Command guidelines](docs/cli-kit/command-guidelines.md): design commands and flags with consistent structure, defaults, and dependencies.
- [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

- [docs/cli-kit/ui-kit/contributing.md](docs/cli-kit/ui-kit/contributing.md)
- [docs/cli-kit/ui-kit/guidelines.md](docs/cli-kit/ui-kit/guidelines.md)
- [docs/cli-kit/ui-kit/readme.md](docs/cli-kit/ui-kit/readme.md)
- [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.
- [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.
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

# Contributors documentation

This page contains resources for people interested in contributing to this repository or developing a [plugin](./plugins.md).
This page contains resources for people interested in contributing to this repository or developing a [plugin](./cli/conventions.md#2---plugins-eg-shopifyapp).

## CLI

The Shopify CLI is a tool for merchants, partners, and developers to interact with the platform from their terminals. Its technical design allows adding features horizontally through [**plugins**](#plugins) that build on [**cli-kit**](#cli-kit). [@shopify/theme](https://www.npmjs.com/package/@shopify/theme), [@shopify/app](https://www.npmjs.com/package/@shopify/app), [@shopify/cli-hydrogen](https://www.npmjs.com/package/@shopify/cli-hydrogen) are examples of plugins to develop themes, apps, and hydrogen storefronts, respectively.
The Shopify CLI is a tool for merchants, partners, and developers to interact with the platform from their terminals. Its technical design allows adding features horizontally through [**plugins**](./cli/conventions.md#2---plugins-eg-shopifyapp) that build on [**cli-kit**](#cli-kit). [@shopify/theme](https://www.npmjs.com/package/@shopify/theme), [@shopify/app](https://www.npmjs.com/package/@shopify/app), [@shopify/cli-hydrogen](https://www.npmjs.com/package/@shopify/cli-hydrogen) are examples of plugins to develop themes, apps, and hydrogen storefronts, respectively.

The list below contains valuable resources for people interested in contributing to the CLI project in this repository.

Expand Down
4 changes: 4 additions & 0 deletions docs/cli-kit/command-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Flags should be semantically meaningful. When in doubt, optimize for clarity, no
| :------------- | :------------- | :------------- | :------------- |
| ❌ | Don't: | rsync --owner | Because it’s unnecessarily terse, it’s ambiguous whether this flag means “preserve the current owner” or “assign ownership”.|

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

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.
Expand Down
20 changes: 19 additions & 1 deletion docs/cli/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { joinPath } from "node:path"
```


Prefer imports from the actual owner over forwarding-only internal wrappers. Preserve deliberate public package entrypoints and index modules that orchestrate behavior; this is not an index-file ban or a package-wide migration.

### 1.2 - Modules free of side effects

Modules must not perform any side effect when they are imported. For example, doing an IO operation at the root of the module:
Expand Down Expand Up @@ -47,6 +49,8 @@ Instead, you can:
- **Store the state in the system.** It leads to IO operations, which impact the performance, but because the state is often little, it's preferred over an unreliable experience.
- **Load and pass the state down:** Load the state upfront, for example, an in-memory representation of the project the CLI is interacting with, and pass it down through function arguments.

For necessary caches or remembered state, define applicable identity, project, store, and environment inputs, lifetime, invalidation, mutation, and unusable-state fallback. Derive auth-sensitive identity from the session or token authorizing the request, not an unrelated global account getter. Do not persist raw credentials in keys; token rotation can cost a cache miss. Test the actual cached path, changed context, and existing mutation/fallback branches. An optional auth lookup can return absence and use normal valid authentication; do not suppress unrelated errors.

### 1.4 - Functions that don't mutate the input arguments

When designing the implementation of a function, refrain from mutating objects that the function receives as arguments. Function callers might design their business logic to assume that the arguments they pass to other functions are not mutated. If they do, the integration might not behave as expected, manifesting as bugs on the user side.
Expand All @@ -64,6 +68,20 @@ but considering the size of the state, the CLI deals with, and optimizations Jav
it shouldn't be an issue.


### 1.5 - Resource lifetime

When starting or changing watchers, servers, listeners, child processes, async tasks, or temporary resources, name the owner of completion, rejection, and cleanup on success, failure, cancellation, and repeated invocation. Observe started promise failures promptly. `Promise.race` observes its inputs but does not dispose losing resources; timeout settlement is not cleanup. Wait for owned processes and descendants to stop before deleting their files. Preserve scoped [filesystem](../../packages/cli-kit/src/public/node/fs.ts) and [process](../../packages/cli-kit/src/public/node/system.ts) helpers, deliberate background owners, and [UI cancellation/cleanup](../cli-kit/ui-kit/contributing.md#handling-user-input).

### 1.6 - Input and artifact IO

Reject locally invalid inputs or flag combinations before authentication, network access, or persistent writes where local validation is available. Validate the representation the parser, executor, or writer consumes. For restricted filesystem access, normalization alone is not containment: use established helpers and the allowed-root, ancestor, and symlink policy. Preserve legitimate paths.

Artifact producers and consumers must agree on format, encoded byte bounds, and applicable encoding. Validate before replacing a valid artifact. Tie confirmation, file, size, and upload to the same serialized bytes. On later failure, clean only owned resources or provide safe recovery. Preserve the original error and pre-existing user content.

### 1.7 - Optional observability

Optional diagnostics or telemetry must not hide successful results, prevent credential persistence, prompt or authenticate unexpectedly, or mutate project files. Keep passive reads bounded, catches narrow, and background ownership explicit. Required security validation, audit, billing, or product-contract work is not automatically optional.

## 2 - Plugins (e.g `@shopify/app`)

### 2.1 - Model-command-service (MCS)
Expand Down Expand Up @@ -106,7 +124,7 @@ app/
##### Definition and responsibilities

Services represent **reusable units of business logic.**
They export a default function representing the service and might contain additional internal combined functions to form the service.
They export a named function representing the service and might contain additional internal combined functions to form the service.
Each command must have a service representing it,
and we might have additional services that don't map to commands.
Note that services are decoupled from commands,
Expand Down
6 changes: 4 additions & 2 deletions docs/cli/cross-os-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ When implementing business logic that interacts with the OS, for example doing I

### Manual testing

Use the Node and PNPM versions required by the repository. See [setup requirements](get-started.md#requirements).

Please don't assume that a successful working workflow in the OS in which it was developed will yield success in other OSs. **We strongly recommend manually testing the workflow in other OSs**.

#### Linux

After installing Ubuntu 22 then run:

- `sudo apt-get update && sudo apt-get -y upgrade`
- `curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -`
- `curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -`
- `sudo apt-get install -y git nodejs`
- `curl -fsSL https://get.pnpm.io/install.sh | sh -`
- `curl -fsSL https://get.pnpm.io/install.sh | env PNPM_VERSION=10.11.1 sh -`

You can clone the CLI repository:

Expand Down
2 changes: 2 additions & 0 deletions docs/cli/debugging.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Debugging

New diagnostics and support artifacts must not expose credentials. Redact before truncation, including parse-failure paths. Inspect relevant stderr, events, files, and artifacts, not only stdout; keep useful nonsecret facts. Existing redaction does not prove that content has no paths or code if that is the disclosure promise. Escalate privacy/compatibility choices instead of silently removing stable legacy fields. See [JSON contracts](json-output.md) and [safe error details](error_handling.md#fatal-errors-in-json-output).

The CLI works well with VS Code's built-in debugger -- feel free to use breakpoints across the constituent packages and Typescript files.

The current recommended practise for testing is to run the "Javascript Debug Terminal" command in VS Code. This launches a terminal where the debugger is automatically attached to any node process. If you there execute `pnpm run shopify` (build and run) or `pnpm run shopify:run` (just run), the CLI will be launched and you can provide any desired arguments for the feature you are testing. As the debugger is automatically attached, any breakpoints you've set will be triggered when they're encountered.
6 changes: 5 additions & 1 deletion docs/cli/error_handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The CLI defines `FatalError` and several subtypes of `FatalError`. Within the CL
* Use `AbortSilentError` for user-initiated cancellations
* Use `ExternalError` when external commands fail

Please, **don't** use the global `process.exit` and `process.abort` APIs. Also, don't `try {} catch {}` abort errors. If you need to communicate the failure of an operation to the caller (e.g., a 5xx HTTP response), use the result type from the following section.
Please, **don't** use the global `process.exit` and `process.abort` APIs. Do not catch abort errors indiscriminately to continue anyway. Catch only a named domain condition that the operation explicitly expects and can recover from, such as `StoreNotFoundError` while waiting for a newly created store. Rethrow unrelated failures, including ordinary auth/session failures, and preserve user cancellation. If you need to communicate the failure of an operation to the caller (e.g., a 5xx HTTP response), use the result type from the following section.

#### AbortError

Expand Down Expand Up @@ -197,6 +197,10 @@ result.valueOrBug() // throws!
result.mapError((error) => new FatalError("other error"))
```

## Narrow recovery and retries

Use stable API codes or domain state for retry decisions when supplied, not broad or localized message matches. Test false-positive messages and unrelated failures. When no structured signal exists, retain justified narrow string handling and test the producer-to-consumer contract; the conservative OS/environment backstop below remains valid.

## Environmental Issue Detection

The CLI has a unique pattern for classifying non-fatal errors as environment issues through `shouldReportErrorAsUnexpected` and `errorMessageImpliesEnvironmentIssue`.
Expand Down
4 changes: 2 additions & 2 deletions docs/cli/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ This wiki contains documentation that's useful for contributors of the project.

If you'd like to contribute to this project, the following system dependencies need to be present in the environment.

- [Node](https://nodejs.org/en/) (v20.10 or higher)
- [PNPM](https://pnpm.io/) (v10)
- [Node](https://nodejs.org/en/): use a supported version that meets the `engines` requirements in [CLI](../../packages/cli/package.json), [app](../../packages/app/package.json), and [CLI Kit](../../packages/cli-kit/package.json).
- [PNPM](https://pnpm.io/): use the version in the root [`packageManager`](../../package.json) field.

### Set up

Expand Down
Loading
Loading