Skip to content

[Feature] Add shopify fetch command to download docs from shopify.dev#7766

Draft
nelsonwittwer wants to merge 7 commits into
telemetry-app-context-everywherefrom
add-fetch-doc-command
Draft

[Feature] Add shopify fetch command to download docs from shopify.dev#7766
nelsonwittwer wants to merge 7 commits into
telemetry-app-context-everywherefrom
add-fetch-doc-command

Conversation

@nelsonwittwer

@nelsonwittwer nelsonwittwer commented Jun 9, 2026

Copy link
Copy Markdown

WHY are these changes introduced?

1. Agents need full contents of page

We have a blindspot for context for agents when the instructions are too long for skill files and/or when we want a centrally managed agent instructions. The app store requirements is a great example of this in action.

The entire contents of a page is needed to be shared with agents, not chunks like our existing search command supports.

2. Agents behavior needs to be tracked

CLI actions give us tracking for free with monorail events. We need to know how often agents are using pages that we ship (like this app store page) and how effective they are.

WHAT is this pull request doing?

Adds a top-level shopify fetch-doc <url> command that downloads a shopify.dev page and prints it to stdout (pipe/capture friendly):

  • Every page on shopify.dev has a Markdown version, and that's what the command returns (requested via the Accept header; shopify.dev returns content-type: text/markdown), so agents get clean, parseable content instead of HTML.
  • A --output <path> flag (-o, env SHOPIFY_FLAG_OUTPUT) writes the document to a file instead of printing it to stdout, creating any missing parent directories.
  • Supports the CLI's standard global flags (--verbose, --no-color).
  • URLs are restricted to shopify.dev (and subdomains) via an extensible allow-list; anything else fails with a clear error.

It mirrors the existing search command's structure (thin oclif command → service function → unit test) and is registered the same way in COMMANDS, so it's automatically tracked by the CLI's analytics hooks like every other command — emitting an app_cli3_command/1.26 Monorail event with command: "fetch-doc". Generated artifacts (oclif manifest, README, shopify.dev docs interface + generated JSON) are regenerated and committed.

This PR also clarifies the search command's description to distinguish the two docs commands by intent — search for chunked discovery (finding the relevant pieces) vs. fetch-doc for verbatim full-document retrieval (loading a whole instruction set, like a centrally-served skill) — and adds the shared global flags to search as well, so the two commands behave consistently.

Note: the command was renamed from fetchfetch-doc and the rejection error was reworded during review, so the screenshots below (captured earlier) still show the old fetch name / wording. Behavior is otherwise unchanged.

My 🎩

# Markdown (default)
pnpm shopify fetch-doc https://shopify.dev/docs/api/shopify-cli
Screenshot 2026-06-09 at 11 02 32 AM
# Save to a file instead of stdout (creates parent directories as needed)
pnpm shopify fetch-doc https://shopify.dev/docs/api/shopify-cli --output docs/shopify-cli.md
# Rejected: non-shopify.dev host
pnpm shopify fetch-doc https://example.com/docs   # → "Only documents from the following hosts can be fetched: shopify.dev."
Screenshot 2026-06-09 at 11 05 07 AM
# Verify the Monorail event fires (forces analytics on in dev; --verbose prints the payload)
SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS=1 pnpm shopify fetch-doc https://shopify.dev/docs/api/shopify-cli --verbose 2>&1 | grep -A40 "Analytics event sent"
# → "command": "fetch-doc", "success": true, "cmd_all_exit": "ok"
Screenshot 2026-06-09 at 11 34 52 AM

Agent confirmation

lol agents will always tell you things work well, though they did tell me to add the --output option and remove the --html option.

Codex

Screenshot 2026-06-09 at 11 47 34 AM

Pi

Screenshot 2026-06-09 at 12 17 44 PM

Claude Code

Screenshot 2026-06-09 at 12 19 17 PM

@nelsonwittwer nelsonwittwer requested review from a team as code owners June 9, 2026 14:15
@github-actions github-actions Bot added the Area: @shopify/cli @shopify/cli package issues label Jun 9, 2026
Comment thread packages/cli/src/cli/commands/fetch.ts Outdated
Comment thread packages/cli/src/cli/services/commands/fetch.ts Outdated
@nelsonwittwer nelsonwittwer marked this pull request as draft June 9, 2026 14:59
Comment thread docs-shopify.dev/commands/interfaces/fetch-doc.interface.ts
Comment thread packages/cli/src/cli/services/commands/fetch-doc.ts
nelsonwittwer and others added 7 commits June 9, 2026 16:04
Adds a top-level `fetch` command that downloads a shopify.dev page and
prints it to stdout. It requests the Markdown representation by default
(via the `Accept` header) and accepts a `--content-type` flag to override
it. URLs are restricted to shopify.dev. This gives agents a way to pull
instructional content from the centralized docs repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Rename command/class from `fetch`/`Fetch` to `fetch-doc`/`FetchDoc`
  (and the service to `fetchDocService`) to avoid an overly generic name.
- Replace the hardcoded shopify.dev host check with an extensible
  `ALLOWED_HOSTS` array constant.
- Regenerate oclif manifest, README, and shopify.dev docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Distinguish the two docs commands by intent:
- search: discovery — surface the most relevant pieces of content.
- fetch-doc: retrieve a complete document verbatim, like a
  centrally-served skill an agent follows in its entirety.

Each description cross-references the other so agents pick the right tool.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ery page

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These commands previously rejected the CLI's standard global flags. Adding
`globalFlags` makes them consistent with the rest of the CLI and lets
`--verbose` surface the Monorail analytics payload for local verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- `--output <path>` (`-o`) writes the document to a file (creating any
  missing parent directories) instead of printing to stdout.
- Remove the `--content-type` flag: fetch-doc now always requests the
  Markdown representation. Returning HTML is noisy and expensive and not
  a behavior we want to encourage.
- Regenerate oclif manifest, README, and shopify.dev docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nelsonwittwer nelsonwittwer force-pushed the add-fetch-doc-command branch from 60b956c to 32e22ff Compare June 9, 2026 20:06
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/public/node/session.d.ts
@@ -47,6 +47,22 @@ export declare function isUserAccount(account: AccountInfo): account is UserAcco
  * @returns True if the account is a ServiceAccount.
  */
 export declare function isServiceAccount(account: AccountInfo): account is ServiceAccountInfo;
+/**
+ * Reports whether the CLI already has stored credentials, without prompting the
+ * user, opening a browser, or making any network request.
+ *
+ * This is a passive, side-effect-free check: it reads the local session store and
+ * returns  when at least one valid session is present. Unlike the
+ *  functions, it never triggers a login flow and never logs
+ * the user out. Because it does not contact the network, it cannot tell whether the
+ * stored token is currently valid/unexpired — only that credentials exist locally.
+ *
+ * Intended for best-effort, opportunistic behaviour (for example, enriching
+ * telemetry only for users who are already logged in).
+ *
+ * @returns True if local credentials exist, false otherwise.
+ */
+export declare function sessionExists(): Promise<boolean>;
 /**
  * Ensure that we have a valid session with no particular scopes.
  *

@nelsonwittwer nelsonwittwer changed the base branch from main to telemetry-app-context-everywhere June 9, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/cli @shopify/cli package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant