Skip to content

Suggest installing the Shopify AI Toolkit for detected AI coding agents#7979

Draft
amcaplan wants to merge 1 commit into
mainfrom
ai-toolkit-detect-agent
Draft

Suggest installing the Shopify AI Toolkit for detected AI coding agents#7979
amcaplan wants to merge 1 commit into
mainfrom
ai-toolkit-detect-agent

Conversation

@amcaplan

@amcaplan amcaplan commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Shopify now offers an AI Toolkit that gives AI coding agents better tooling (skills, dev-mcp, code validation) for building on Shopify. Agents driving Shopify CLI (Pi, Claude Code, Codex, etc.) don't know about it unless a human tells them.

WHAT is this pull request doing?

  • Adds packages/cli-kit/src/public/node/ai-agent-toolkit.ts:
    • detectAIAgentHarness(env) — identifies the harness running the process via known env vars: PI_CODING_AGENT (Pi), CLAUDE_CODE (Claude Code), CODEX_THREAD_ID (Codex).
    • isRunningInsideAIAgent(env) — true when stdout is non-TTY and a harness env var is present.
    • isAIToolkitInstalled(harness) — best-effort, harness-specific check:
      • Pi: looks for any shopify-* skill directory under ~/.pi/agent/skills.
      • Claude Code: looks for shopify in ~/.claude/plugins/installed_plugins.json, falling back to the plugin cache directory.
      • Codex: looks for shopify in ~/.codex/config.toml, falling back to the plugin cache directory.
    • suggestAIToolkitInstallIfNeeded(env) — when running inside a detected agent without the toolkit installed, prints the install command for that harness plus a link to the docs, via outputInfo.
  • Wires suggestAIToolkitInstallIfNeeded() into BaseCommand#init() so the message prints at the very start of command execution, before any other work happens.
  • Adds unit tests covering harness detection, TTY gating, per-harness installed-detection, and the end-to-end suggestion flow.
  • Adds a changeset.

How to test your changes?

CLAUDE_CODE=1 pnpm shopify version < /dev/null

(piping stdin makes stdout non-interactive in most shells/CI runners; alternatively run inside an actual agent harness)

You should see a line suggesting claude plugin install shopify-ai-toolkit@claude-plugins-official (unless the plugin is already installed locally). Swap CLAUDE_CODE for PI_CODING_AGENT or CODEX_THREAD_ID to see the Pi/Codex variants.

Unit tests: pnpm vitest run packages/cli-kit/src/public/node/ai-agent-toolkit.test.ts

Detects when Shopify CLI is being run by an AI coding agent (Pi,
Claude Code, Codex) using a combination of a non-TTY stdout and a
known harness environment variable (PI_CODING_AGENT, CLAUDE_CODE,
CODEX_THREAD_ID). If the Shopify AI Toolkit isn't already installed
for that harness, prints a line at the start of command execution
telling the agent how to install it, per
https://shopify.dev/docs/apps/build/ai-toolkit.

Assisted-By: devx/02722c6b-83ec-413e-9eb9-236c0943393c
Copilot AI review requested due to automatic review settings July 1, 2026 22:06
@amcaplan amcaplan requested review from a team as code owners July 1, 2026 22:06
@github-actions github-actions Bot added the Area: @shopify/cli @shopify/cli package issues label Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 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

packages/cli-kit/dist/public/node/ai-agent-toolkit.d.ts
/**
 * The AI coding agent harnesses that the CLI knows how to detect.
 */
export type AIAgentHarness = 'pi' | 'claude-code' | 'codex';
/**
 * Detects which AI coding agent harness (if any) is running the current process, based on
 * well-known environment variables set by each harness.
 *
 * @param env - The environment variables from the environment of the current process.
 * @returns The detected harness, or undefined if none was detected.
 */
export declare function detectAIAgentHarness(env?: NodeJS.ProcessEnv): AIAgentHarness | undefined;
/**
 * Returns true if the CLI is likely being driven by an AI coding agent rather than a human in
 * an interactive terminal. This is a best-effort heuristic based on the absence of a TTY
 * combined with the presence of a known agent harness environment variable.
 *
 * @param env - The environment variables from the environment of the current process.
 * @returns True if the current process appears to be running inside an AI coding agent.
 */
export declare function isRunningInsideAIAgent(env?: NodeJS.ProcessEnv): boolean;
/**
 * Checks whether the Shopify AI Toolkit is installed for the given harness.
 *
 * @param harness - The AI agent harness to check.
 * @returns True if the toolkit appears to be installed.
 */
export declare function isAIToolkitInstalled(harness: AIAgentHarness): Promise<boolean>;
/**
 * Returns the shell command an AI agent should run to install the Shopify AI Toolkit for the
 * given harness.
 *
 * @param harness - The AI agent harness.
 * @returns The install command for the harness.
 */
export declare function aiToolkitInstallCommand(harness: AIAgentHarness): string;
/**
 * Returns the human-friendly display name for a harness.
 *
 * @param harness - The AI agent harness.
 * @returns The display name for the harness.
 */
export declare function aiAgentHarnessName(harness: AIAgentHarness): string;
/**
 * If the current process appears to be running inside a known AI coding agent and the Shopify
 * AI Toolkit isn't installed for that agent, prints a message telling the agent how to install
 * it. This is a no-op when running interactively, when no known harness is detected, or when the
 * toolkit is already installed.
 *
 * @param env - The environment variables from the environment of the current process.
 */
export declare function suggestAIToolkitInstallIfNeeded(env?: NodeJS.ProcessEnv): Promise<void>;

Existing type declarations

We found no diffs with existing type declarations

@amcaplan amcaplan marked this pull request as draft July 1, 2026 22:09

Copilot AI left a comment

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.

Pull request overview

Introduces an early-startup hint in @shopify/cli-kit to detect when Shopify CLI is being run under known AI coding agent harnesses (Pi, Claude Code, Codex) and, if the Shopify AI Toolkit is not detected, emit an outputInfo message with an install command and docs link.

Changes:

  • Add AI-agent harness detection + toolkit “installed” heuristics and a single suggestAIToolkitInstallIfNeeded() entrypoint.
  • Invoke the suggestion hook at the beginning of BaseCommand#init() so it runs before other command work.
  • Add Vitest coverage for detection, gating, per-harness install checks, and message emission; include a changeset.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
packages/cli-kit/src/public/node/base-command.ts Calls the new suggestion hook during command initialization.
packages/cli-kit/src/public/node/ai-agent-toolkit.ts Implements harness detection, install detection heuristics, and suggestion output.
packages/cli-kit/src/public/node/ai-agent-toolkit.test.ts Adds unit tests for harness detection, TTY gating, install detection, and suggestion output.
.changeset/suggest-ai-toolkit-install.md Declares a patch changeset for the new user-visible messaging.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +50 to +51
const {suggestAIToolkitInstallIfNeeded} = await import('./ai-agent-toolkit.js')
await suggestAIToolkitInstallIfNeeded()
Comment on lines +135 to +137
export function isRunningInsideAIAgent(env = process.env): boolean {
return !process.stdout.isTTY && detectAIAgentHarness(env) !== undefined
}
Comment on lines +61 to +63
const installedPluginsFile = joinPath(homeDirectory(), '.claude', 'plugins', 'installed_plugins.json')
if (await fileContains(installedPluginsFile, 'shopify')) return true

Comment on lines +68 to +72
for (const marketplace of marketplaces) {
// eslint-disable-next-line no-await-in-loop
const plugins = await directoryEntries(joinPath(cacheDirectory, marketplace))
if (plugins.some((plugin) => plugin.includes('shopify'))) return true
}
Comment on lines +77 to +79
const configFile = joinPath(homeDirectory(), '.codex', 'config.toml')
if (await fileContains(configFile, 'shopify')) return true

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.

2 participants