Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
94eccfb
Expose app dev session files for agents
isaacroldan Oct 19, 2026
42ae66e
Document session identity in the dev status file
isaacroldan Oct 19, 2026
7639115
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
2fb508f
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
3a4f92a
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
3f0eb50
Keep app dev log messages and status transitions aligned with termina…
isaacroldan Oct 20, 2026
6ef6660
Add typed JSON output to app dev
isaacroldan Oct 20, 2026
5755b1c
Omit event type from app dev JSONL output
isaacroldan Oct 20, 2026
410d6f7
Write identical app dev JSONL to stdout and the session log
isaacroldan Oct 20, 2026
3f876a3
Remove stream from app dev JSONL records
isaacroldan Oct 20, 2026
6a4e1c3
Update app dev to the shared session log API
isaacroldan Oct 20, 2026
390d0a3
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 20, 2026
f00458d
Move app dev session ownership into the service
isaacroldan Oct 20, 2026
07014f3
Restore app dev command description
isaacroldan Oct 20, 2026
edc660a
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
cfec7e3
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 20, 2026
d0694df
Limit app dev session logs to the dev stream
isaacroldan Oct 20, 2026
0858500
Own app dev sessions in the service
isaacroldan Oct 20, 2026
31bed5c
Merge shared app dev lifecycle changes from PR 8926
isaacroldan Oct 20, 2026
ea423d4
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
c85ff99
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 20, 2026
991d4ad
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
d10235f
Document the 15-second dev stale interval
isaacroldan Oct 20, 2026
d0f6cfd
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 20, 2026
15e4692
Flush app dev output before signal shutdown
isaacroldan Oct 20, 2026
35b94ce
Capture Javy diagnostics in dev session logs
isaacroldan Oct 20, 2026
48331ed
Merge app dev shutdown and compiler log fixes
isaacroldan Oct 20, 2026
cf87f17
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
37aa420
Document dev log discovery with identity hashes
isaacroldan Oct 20, 2026
d84e721
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 20, 2026
7cbd5c5
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 20, 2026
83b176a
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 20, 2026
b25f53b
Run dev shutdown subprocess tests from workspace sources
isaacroldan Oct 20, 2026
044ba7f
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 20, 2026
77ab941
Give each JSON dev process its own output sink
isaacroldan Oct 21, 2026
ec08bdd
Exit non-interactive dev after the postrun hook
isaacroldan Oct 21, 2026
a9a3ae1
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 21, 2026
ce1708a
Cover single-signal shutdown in JSON mode
isaacroldan Oct 21, 2026
0575768
Separate complete messages in non-interactive dev output
isaacroldan Oct 21, 2026
0e251e2
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 21, 2026
3d4fd43
Merge branch 'codex/dev-instance-support' into make-dev-agentic
isaacroldan Oct 21, 2026
1ae5360
Use scoped dev instance ownership in the app service
isaacroldan Oct 21, 2026
652277a
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 21, 2026
3934b61
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 21, 2026
2866926
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 22, 2026
a6a9507
Expose app dev session-file schemas
isaacroldan Oct 22, 2026
d54e974
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 22, 2026
0806daa
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 22, 2026
087dc01
Check named definitions in documentation schemas
isaacroldan Oct 22, 2026
cefa9cd
Merge branch 'make-dev-agentic' into codex/app-dev-json
isaacroldan Oct 22, 2026
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: 5 additions & 0 deletions .changeset/bright-dev-stream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli': minor
---

Add `app dev --json` streaming and expose session-file schemas with `--json-schema`.
11 changes: 10 additions & 1 deletion docs-shopify.dev/generated/generated_docs_data_v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,15 @@
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_APP_CONFIG"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/app-dev.interface.ts",
"syntaxKind": "PropertySignature",
"name": "-j, --json",
"value": "''",
"description": "Output the result as JSON. Automatically disables color output.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_JSON"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/app-dev.interface.ts",
"syntaxKind": "PropertySignature",
Expand All @@ -1421,7 +1430,7 @@
"environmentValue": "SHOPIFY_FLAG_THEME"
}
],
"value": "export interface appdev {\n /**\n * Alias of the Shopify account to use for authentication.\n * @environment SHOPIFY_FLAG_AUTH_ALIAS\n */\n '--auth-alias <value>'?: string\n\n /**\n * Resource URL for checkout UI extension. Format: \"/cart/{productVariantID}:{productQuantity}\"\n * @environment SHOPIFY_FLAG_CHECKOUT_CART_URL\n */\n '--checkout-cart-url <value>'?: string\n\n /**\n * The Client ID of your app. Use with --config to run dev with that configuration for a different app than the one it is linked to.\n * @environment SHOPIFY_FLAG_CLIENT_ID\n */\n '--client-id <value>'?: string\n\n /**\n * The name of the app configuration.\n * @environment SHOPIFY_FLAG_APP_CONFIG\n */\n '-c, --config <value>'?: string\n\n /**\n * Install and use mkcert to generate localhost certificates when --use-localhost is enabled without prompting.\n * @environment SHOPIFY_FLAG_INSTALL_MKCERT\n */\n '--install-mkcert'?: ''\n\n /**\n * Print the command's JSON schemas.\n * @environment SHOPIFY_FLAG_JSON_SCHEMA\n */\n '--json-schema'?: ''\n\n /**\n * Port to use for localhost. Must be between 1 and 65535.\n * @environment SHOPIFY_FLAG_LOCALHOST_PORT\n */\n '--localhost-port <value>'?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Disable interactive prompts and browser authentication.\n * @environment SHOPIFY_FLAG_NO_INPUT\n */\n '--no-input'?: ''\n\n /**\n * Uses the app URL from the toml file instead an autogenerated URL for dev.\n * @environment SHOPIFY_FLAG_NO_UPDATE\n */\n '--no-update'?: ''\n\n /**\n * The file path or URL. The file path is to a file that you want updated on idle. The URL path is where you want a webhook posted to report on file changes.\n * @environment SHOPIFY_FLAG_NOTIFY\n */\n '--notify <value>'?: string\n\n /**\n * The path to your app directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path <value>'?: string\n\n /**\n * Reset all your settings.\n * @environment SHOPIFY_FLAG_RESET\n */\n '--reset'?: ''\n\n /**\n * Skips the installation of dependencies. Deprecated, use workspaces instead.\n * @environment SHOPIFY_FLAG_SKIP_DEPENDENCIES_INSTALLATION\n */\n '--skip-dependencies-installation'?: ''\n\n /**\n * Store URL. Must be an existing development or Shopify Plus sandbox store.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <value>'?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password <value>'?: string\n\n /**\n * Resource URL for subscription UI extension. Format: \"/products/{productId}\"\n * @environment SHOPIFY_FLAG_SUBSCRIPTION_PRODUCT_URL\n */\n '--subscription-product-url <value>'?: string\n\n /**\n * Theme ID or name of the theme app extension host theme.\n * @environment SHOPIFY_FLAG_THEME\n */\n '-t, --theme <value>'?: string\n\n /**\n * Local port of the theme app extension development server. Must be between 1 and 65535.\n * @environment SHOPIFY_FLAG_THEME_APP_EXTENSION_PORT\n */\n '--theme-app-extension-port <value>'?: string\n\n /**\n * Use a custom tunnel, it must be running before executing dev. Format: \"https://my-tunnel-url:port\".\n * @environment SHOPIFY_FLAG_TUNNEL_URL\n */\n '--tunnel-url <value>'?: string\n\n /**\n * Allow app dev to continue with warnings for eligible app version validation failures.\n * @environment SHOPIFY_FLAG_UNSAFE_VALIDATION\n */\n '--unsafe-validation'?: ''\n\n /**\n * Service entry point will listen to localhost. A tunnel won't be used. Will work for testing many app features, but not those that directly invoke your app (E.g: Webhooks)\n * @environment SHOPIFY_FLAG_USE_LOCALHOST\n */\n '--use-localhost'?: ''\n\n /**\n * Increase the verbosity of the output. May include sensitive data.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}"
"value": "export interface appdev {\n /**\n * Alias of the Shopify account to use for authentication.\n * @environment SHOPIFY_FLAG_AUTH_ALIAS\n */\n '--auth-alias <value>'?: string\n\n /**\n * Resource URL for checkout UI extension. Format: \"/cart/{productVariantID}:{productQuantity}\"\n * @environment SHOPIFY_FLAG_CHECKOUT_CART_URL\n */\n '--checkout-cart-url <value>'?: string\n\n /**\n * The Client ID of your app. Use with --config to run dev with that configuration for a different app than the one it is linked to.\n * @environment SHOPIFY_FLAG_CLIENT_ID\n */\n '--client-id <value>'?: string\n\n /**\n * The name of the app configuration.\n * @environment SHOPIFY_FLAG_APP_CONFIG\n */\n '-c, --config <value>'?: string\n\n /**\n * Install and use mkcert to generate localhost certificates when --use-localhost is enabled without prompting.\n * @environment SHOPIFY_FLAG_INSTALL_MKCERT\n */\n '--install-mkcert'?: ''\n\n /**\n * Output the result as JSON. Automatically disables color output.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Print the command's JSON schemas.\n * @environment SHOPIFY_FLAG_JSON_SCHEMA\n */\n '--json-schema'?: ''\n\n /**\n * Port to use for localhost. Must be between 1 and 65535.\n * @environment SHOPIFY_FLAG_LOCALHOST_PORT\n */\n '--localhost-port <value>'?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Disable interactive prompts and browser authentication.\n * @environment SHOPIFY_FLAG_NO_INPUT\n */\n '--no-input'?: ''\n\n /**\n * Uses the app URL from the toml file instead an autogenerated URL for dev.\n * @environment SHOPIFY_FLAG_NO_UPDATE\n */\n '--no-update'?: ''\n\n /**\n * The file path or URL. The file path is to a file that you want updated on idle. The URL path is where you want a webhook posted to report on file changes.\n * @environment SHOPIFY_FLAG_NOTIFY\n */\n '--notify <value>'?: string\n\n /**\n * The path to your app directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path <value>'?: string\n\n /**\n * Reset all your settings.\n * @environment SHOPIFY_FLAG_RESET\n */\n '--reset'?: ''\n\n /**\n * Skips the installation of dependencies. Deprecated, use workspaces instead.\n * @environment SHOPIFY_FLAG_SKIP_DEPENDENCIES_INSTALLATION\n */\n '--skip-dependencies-installation'?: ''\n\n /**\n * Store URL. Must be an existing development or Shopify Plus sandbox store.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <value>'?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password <value>'?: string\n\n /**\n * Resource URL for subscription UI extension. Format: \"/products/{productId}\"\n * @environment SHOPIFY_FLAG_SUBSCRIPTION_PRODUCT_URL\n */\n '--subscription-product-url <value>'?: string\n\n /**\n * Theme ID or name of the theme app extension host theme.\n * @environment SHOPIFY_FLAG_THEME\n */\n '-t, --theme <value>'?: string\n\n /**\n * Local port of the theme app extension development server. Must be between 1 and 65535.\n * @environment SHOPIFY_FLAG_THEME_APP_EXTENSION_PORT\n */\n '--theme-app-extension-port <value>'?: string\n\n /**\n * Use a custom tunnel, it must be running before executing dev. Format: \"https://my-tunnel-url:port\".\n * @environment SHOPIFY_FLAG_TUNNEL_URL\n */\n '--tunnel-url <value>'?: string\n\n /**\n * Allow app dev to continue with warnings for eligible app version validation failures.\n * @environment SHOPIFY_FLAG_UNSAFE_VALIDATION\n */\n '--unsafe-validation'?: ''\n\n /**\n * Service entry point will listen to localhost. A tunnel won't be used. Will work for testing many app features, but not those that directly invoke your app (E.g: Webhooks)\n * @environment SHOPIFY_FLAG_USE_LOCALHOST\n */\n '--use-localhost'?: ''\n\n /**\n * Increase the verbosity of the output. May include sensitive data.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}"
}
},
"appenvpull": {
Expand Down
16 changes: 11 additions & 5 deletions docs/cli/dev-instance-agent-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,18 @@ of commits and external reports; output and local URLs can contain secrets.
## App dev

`shopify app dev` owns one session per app configuration. The instance details
include the app configuration, app identity, store, URLs, and `preview`:
include the app configuration, app identity, store, URLs, and `preview`.

- `state`: `starting`, `updating`, `ready`, or `error`.
- `message`: the current CLI status message, or `null` before one is available.
- `errors`: the current reported errors. Errors remain during retries and clear
when the CLI reports success.
Use `shopify app dev --json-schema` to inspect the contract. `definitions.DevInstance`

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.

👌

describes the saved instance JSON, and `definitions.DevPreview` describes
`details.preview`. `definitions.Result` describes each JSONL stream record.
The instance metadata is stored in the file; it is not added to the JSONL stream.
Preview errors remain during retries and clear when the CLI reports success.

Process messages keep their terminal source, including extension handles.
Changes to the status message also produce a log record with source `app dev`.

With `--json`, dev stream records use identical JSONL bytes in stdout and the session
log. The log contains process output, preview URLs, and session status messages.
CLI setup messages and other diagnostics use stderr. Fatal CLI errors use the
standard JSON error output on stdout and are not added to the session log.
17 changes: 17 additions & 0 deletions docs/cli/json-output.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,23 @@ events from stderr; missing required input then produces a fatal error instead o

## Exempt only streaming commands

`shopify app dev --json` writes dev stream records as identical JSONL bytes to stdout and the session log. Each record
has `timestamp`, `source`, and `message`, with `level` when available. The log contains process output, preview URLs,
and session status messages. There is no final success result. Preview errors remain log records so that the
developer can fix the app while dev keeps running.

CLI setup messages and other diagnostics use stderr. Fatal CLI failures use the standard `{error: {...}}` envelope
on stdout and exit nonzero. These failures are not added to the session log. A second invocation that cannot acquire
the session never changes the running process's log.

```jsonl
{"timestamp":"2026-10-20T09:00:00Z","source":"web","message":"Server listening on 3000"}
{"timestamp":"2026-10-20T09:00:01Z","source":"app dev","level":"info","message":"Ready, watching for changes in your app"}
```

Setup prompts still use stderr. Use `--json --no-input` for unattended runs. `app dev --json-schema` describes the
stream's event and fatal error formats. This streaming contract does not change the single-document rule for finite commands.

Long-lived commands that produce an open-ended event stream don't have one finite result. Track these exemptions in
`packages/eslint-plugin-cli/rules/json-output-command-exceptions.js`, in its streaming section. Add the command's
repository-relative path:
Expand Down
Loading
Loading