Skip to content

Add doc fetch command (download docs from shopify.dev)#7766

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

Add doc fetch command (download docs from shopify.dev)#7766
nelsonwittwer wants to merge 8 commits into
telemetry-app-context-everywherefrom
add-fetch-doc-command

Conversation

@nelsonwittwer

@nelsonwittwer nelsonwittwer commented Jun 9, 2026

Copy link
Copy Markdown

What

Adds shopify doc fetch <url>, which downloads a complete document from shopify.dev and prints it to stdout (or writes it to a file with --output).

This is part of the new doc namespace for documentation tooling — the "full document" half. The "discovery" half is doc search (#7770).

Why

Every page on shopify.dev has a Markdown representation. doc fetch requests that representation, giving agents (and scripts) a clean, verbatim way to pull instructional content from the centralized docs — for example, a set of instructions an agent follows like a centrally-served skill.

Details

  • shopify doc fetch <url> — requests the Markdown version of the page.
  • --output <path> (-o) — write to a file instead of stdout.
  • Only shopify.dev (and subdomains) URLs are allowed; malformed/disallowed URLs and non-ok responses throw before any output.
shopify doc fetch https://shopify.dev/docs/api/shopify-cli
shopify doc fetch https://shopify.dev/docs/api/shopify-cli --output docs/shopify-cli.md

Notes

  • @shopify/cli: minor.
  • Lives under the doc topic (commands/doc/fetch.ts, registered as doc:fetch); adds a doc topic description.
  • Generated artifacts regenerated (oclif manifest, README, dev-docs interface, e2e command-tree snapshot).
  • Branches off telemetry-app-context-everywhere (Capture app context (api_key/project_type) in analytics for every command #7771), so it inherits the app-context telemetry hook automatically.

Related

🤖 Generated with Claude Code

@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/doc-fetch.interface.ts
Comment thread packages/cli/src/cli/services/commands/fetch-doc.ts Outdated
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
@nelsonwittwer nelsonwittwer changed the base branch from main to telemetry-app-context-everywhere June 9, 2026 20:12
Per the doc-namespace plan, documentation commands live under a `doc`
topic. Rename `fetch-doc` → `doc fetch`:

- commands/doc/fetch.ts (class DocFetch), services/commands/doc/fetch.ts
  (docFetchService), and the colocated test.
- Register as `doc:fetch`; add a `doc` topic description.
- Update cross-references (`search` now points to `doc fetch`; `doc fetch`
  points to `doc search`).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nelsonwittwer nelsonwittwer changed the title [Feature] Add shopify fetch command to download docs from shopify.dev Add doc fetch command (download docs from shopify.dev) Jun 10, 2026
@github-actions

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/common/url.d.ts
@@ -12,20 +12,4 @@ export declare function isValidURL(url: string): boolean;
  * @param url - The string to parse into a URL.
  * @returns A URL object if the parsing is successful, undefined otherwise.
  */
-export declare function safeParseURL(url: string): URL | undefined;
-/**
- * Extracts the lowercased hostname from a URL-shaped string. Tolerates
- * bare hosts (without a scheme) and inputs that come back from APIs as
- * either  or .
- *
- * @param value - A URL or bare host string, possibly null/undefined.
- * @returns The lowercased hostname, or undefined when the input is empty.
- */
-export declare function extractHost(value: string | null | undefined): string | undefined;
-/**
- * Extracts the subdomain handle from a  URL or host.
- *
- * @param value - A URL or host string, possibly null/undefined.
- * @returns The myshopify subdomain handle, or undefined when the input isn't a  URL.
- */
-export declare function extractMyshopifyHandle(value: string | null | undefined): string | undefined;
\ No newline at end of file
+export declare function safeParseURL(url: string): URL | undefined;
\ No newline at end of file
packages/cli-kit/dist/public/node/metadata.d.ts
@@ -38,7 +38,6 @@ type CmdFieldsFromMonorail = PickByPrefix<MonorailEventPublic, 'cmd_all_'> & Pic
 declare const coreData: RuntimeMetadataManager<CmdFieldsFromMonorail, {
     commandStartOptions: {
         startTime: number;
-        endTime?: number;
         startCommand: string;
         startTopic?: string;
         startArgs: string[];
@@ -59,7 +58,6 @@ declare const coreData: RuntimeMetadataManager<CmdFieldsFromMonorail, {
 export declare const getAllPublicMetadata: () => Partial<CmdFieldsFromMonorail>, getAllSensitiveMetadata: () => Partial<{
     commandStartOptions: {
         startTime: number;
-        endTime?: number;
         startCommand: string;
         startTopic?: string;
         startArgs: string[];
@@ -79,7 +77,6 @@ export declare const getAllPublicMetadata: () => Partial<CmdFieldsFromMonorail>,
 }, "store_", never>>, addPublicMetadata: (getData: ProvideMetadata<CmdFieldsFromMonorail>, onError?: MetadataErrorHandling) => Promise<void>, addSensitiveMetadata: (getData: ProvideMetadata<{
     commandStartOptions: {
         startTime: number;
-        endTime?: number;
         startCommand: string;
         startTopic?: string;
         startArgs: string[];
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.
  *

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