From c79a4f77f4799c60c997d97ef8a582e6f4505e5b Mon Sep 17 00:00:00 2001 From: Mohith Gajjela <109003762+Mohith26@users.noreply.github.com> Date: Tue, 28 Jul 2026 19:31:25 -0500 Subject: [PATCH 1/2] fix(create): report Intent as skipped when --no-install is used TanStack Intent discovers skills by walking installed node_modules, so running `@tanstack/intent install --map` in a project scaffolded with --no-install finds nothing and writes no AGENTS.md, while the CLI still reported 'TanStack Intent configured' and the closing next steps claimed the agent config 'was wired up'. Skip the Intent step when dependency installation is skipped, report it as skipped, and point the next steps at the follow-up commands to run after installing dependencies. Fixes #495 --- packages/create/src/create-app.ts | 23 ++++++++++++-- packages/create/src/edge-create-app.ts | 35 ++++++++++++++++++++-- packages/create/src/integrations/intent.ts | 16 ++++++++++ 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/packages/create/src/create-app.ts b/packages/create/src/create-app.ts index acb4f970..5ee34ee2 100644 --- a/packages/create/src/create-app.ts +++ b/packages/create/src/create-app.ts @@ -4,6 +4,8 @@ import { isBase64, isDemoFilePath } from './file-helpers.js' import { formatCommand } from './utils.js' import { writeConfigFileToEnvironment } from './config-file.js' import { + getPackageManagerExecuteCommand, + getPackageManagerInstallCommand, getPackageManagerScriptCommand, packageManagerInstall, translateExecuteCommand, @@ -413,9 +415,24 @@ function buildNextSteps(options: Options): string { sections.push(`Docs for the integrations you picked:\n${docLines.join('\n')}`) } if (options.intent) { - sections.push( - `Working with an AI agent? Your agent config (AGENTS.md / CLAUDE.md) was wired up by TanStack Intent\nwith explicit skill mappings for the libraries you installed. Try asking your agent:\n • "migrate this Next.js page to TanStack Start"\n • "add a protected /dashboard route"\n • "show me how to use TanStack Router search params"`, - ) + if (options.install === false) { + const installCommand = formatCommand( + getPackageManagerInstallCommand(options.packageManager), + ) + const intentCommand = formatCommand( + getPackageManagerExecuteCommand(options.packageManager, '@tanstack/intent', [ + 'install', + '--map', + ]), + ) + sections.push( + `Working with an AI agent? TanStack Intent was skipped because dependency installation was\nskipped, so no agent config (AGENTS.md / CLAUDE.md) was written. After installing dependencies,\nwire it up with:\n % ${installCommand}\n % ${intentCommand}`, + ) + } else { + sections.push( + `Working with an AI agent? Your agent config (AGENTS.md / CLAUDE.md) was wired up by TanStack Intent\nwith explicit skill mappings for the libraries you installed. Try asking your agent:\n • "migrate this Next.js page to TanStack Start"\n • "add a protected /dashboard route"\n • "show me how to use TanStack Router search params"`, + ) + } } return sections.length > 0 ? `\nNext steps:\n\n${sections.join('\n\n')}\n` : '' diff --git a/packages/create/src/edge-create-app.ts b/packages/create/src/edge-create-app.ts index 624ccdfd..f036747f 100644 --- a/packages/create/src/edge-create-app.ts +++ b/packages/create/src/edge-create-app.ts @@ -7,6 +7,7 @@ import { resolvePackageJSONLatest } from './npm-resolver.js' import { writeConfigFileToEnvironment } from './edge-config-file.js' import { getPackageManagerExecuteCommand, + getPackageManagerInstallCommand, getPackageManagerScriptCommand, packageManagerInstall, translateExecuteCommand, @@ -255,6 +256,19 @@ async function setupIntent( return } + if (options.install === false) { + environment.startStep({ + id: 'setup-intent', + type: 'info', + message: 'Skipping TanStack Intent setup...', + }) + environment.finishStep( + 'setup-intent', + 'TanStack Intent setup skipped: no dependencies installed yet', + ) + return + } + environment.startStep({ id: 'setup-intent', type: 'command', @@ -531,9 +545,24 @@ function buildNextSteps(options: Options): string { sections.push(`Docs for the integrations you picked:\n${docLines.join('\n')}`) } if (options.intent) { - sections.push( - `Working with an AI agent? Your agent config (AGENTS.md / CLAUDE.md) was wired up by TanStack Intent\nwith explicit skill mappings for the libraries you installed. Try asking your agent:\n - "migrate this Next.js page to TanStack Start"\n - "add a protected /dashboard route"\n - "show me how to use TanStack Router search params"`, - ) + if (options.install === false) { + const installCommand = formatCommand( + getPackageManagerInstallCommand(options.packageManager), + ) + const intentCommand = formatCommand( + getPackageManagerExecuteCommand(options.packageManager, '@tanstack/intent', [ + 'install', + '--map', + ]), + ) + sections.push( + `Working with an AI agent? TanStack Intent was skipped because dependency installation was\nskipped, so no agent config (AGENTS.md / CLAUDE.md) was written. After installing dependencies,\nwire it up with:\n % ${installCommand}\n % ${intentCommand}`, + ) + } else { + sections.push( + `Working with an AI agent? Your agent config (AGENTS.md / CLAUDE.md) was wired up by TanStack Intent\nwith explicit skill mappings for the libraries you installed. Try asking your agent:\n - "migrate this Next.js page to TanStack Start"\n - "add a protected /dashboard route"\n - "show me how to use TanStack Router search params"`, + ) + } } return sections.length > 0 ? `\nNext steps:\n\n${sections.join('\n\n')}\n` : '' diff --git a/packages/create/src/integrations/intent.ts b/packages/create/src/integrations/intent.ts index 0dd6212f..667befd3 100644 --- a/packages/create/src/integrations/intent.ts +++ b/packages/create/src/integrations/intent.ts @@ -13,6 +13,22 @@ export async function setupIntent( return } + if (options.install === false) { + const s = environment.spinner() + s.start('Skipping TanStack Intent setup...') + environment.startStep({ + id: 'setup-intent', + type: 'info', + message: 'Skipping TanStack Intent setup...', + }) + environment.finishStep( + 'setup-intent', + 'TanStack Intent setup skipped: no dependencies installed yet', + ) + s.stop('TanStack Intent setup skipped: no dependencies installed yet') + return + } + const s = environment.spinner() s.start('Setting up TanStack Intent skill mappings...') environment.startStep({ From c72113b3a9fd226a6fa2771f3fdff8d7eb1a1291 Mon Sep 17 00:00:00 2001 From: Mohith Gajjela <109003762+Mohith26@users.noreply.github.com> Date: Tue, 28 Jul 2026 19:32:10 -0500 Subject: [PATCH 2/2] test(create): cover intent setup skip under --no-install Add regression tests for #495: setupIntent must not run the intent install command when dependency installation is skipped, and the closing next steps must report the skip with follow-up commands instead of claiming the agent config was wired up. --- packages/create/tests/create-app.test.ts | 42 +++++++++++ .../create/tests/integrations/intent.test.ts | 69 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 packages/create/tests/integrations/intent.test.ts diff --git a/packages/create/tests/create-app.test.ts b/packages/create/tests/create-app.test.ts index fe2b481d..91cd0894 100644 --- a/packages/create/tests/create-app.test.ts +++ b/packages/create/tests/create-app.test.ts @@ -124,6 +124,48 @@ describe('createApp', () => { }) }) + it('skips intent setup and reports the follow-up when dependency install is skipped', async () => { + const { environment, output } = createMemoryEnvironment() + let outro = '' + environment.outro = (message: string) => { + outro = message + } + await createApp(environment, { + ...simpleOptions, + intent: true, + install: false, + }) + + expect(output.commands).not.toContainEqual({ + command: 'pnpm', + args: ['dlx', '@tanstack/intent', 'install', '--map'], + }) + expect(outro).not.toContain('was wired up by TanStack Intent') + expect(outro).toContain('TanStack Intent was skipped') + expect(outro).toContain('pnpm install') + expect(outro).toContain('pnpm dlx @tanstack/intent install --map') + }) + + it('sets up intent and reports the agent config when dependencies are installed', async () => { + const { environment, output } = createMemoryEnvironment() + let outro = '' + environment.outro = (message: string) => { + outro = message + } + await createApp(environment, { + ...simpleOptions, + intent: true, + install: true, + }) + + expect(output.commands).toContainEqual({ + command: 'pnpm', + args: ['dlx', '@tanstack/intent', 'install', '--map'], + }) + expect(outro).toContain('was wired up by TanStack Intent') + expect(outro).not.toContain('TanStack Intent was skipped') + }) + it('should create an app - with a add-on', async () => { const { environment, output } = createMemoryEnvironment() await createApp(environment, { diff --git a/packages/create/tests/integrations/intent.test.ts b/packages/create/tests/integrations/intent.test.ts new file mode 100644 index 00000000..2c2fdad0 --- /dev/null +++ b/packages/create/tests/integrations/intent.test.ts @@ -0,0 +1,69 @@ +import { describe, expect, it } from 'vitest' + +import { createMemoryEnvironment } from '../../src/environment.js' +import { setupIntent } from '../../src/integrations/intent.js' + +import type { Options } from '../../src/types.js' + +describe('intent', () => { + it('should skip if intent is not enabled', async () => { + const { environment, output } = createMemoryEnvironment() + environment.startRun() + await setupIntent(environment, '/test', { + packageManager: 'pnpm', + intent: false, + projectName: 'test', + typescript: true, + spinner: () => ({ + start: () => {}, + stop: () => {}, + }), + } as unknown as Options) + environment.finishRun() + + expect(output.commands).toEqual([]) + }) + + it('should run the intent install command when dependencies are installed', async () => { + const { environment, output } = createMemoryEnvironment() + environment.startRun() + await setupIntent(environment, '/test', { + packageManager: 'pnpm', + intent: true, + install: true, + projectName: 'test', + typescript: true, + spinner: () => ({ + start: () => {}, + stop: () => {}, + }), + } as unknown as Options) + environment.finishRun() + + expect(output.commands).toEqual([ + { + command: 'pnpm', + args: ['dlx', '@tanstack/intent', 'install', '--map'], + }, + ]) + }) + + it('should skip the intent install command when dependency install is skipped', async () => { + const { environment, output } = createMemoryEnvironment() + environment.startRun() + await setupIntent(environment, '/test', { + packageManager: 'pnpm', + intent: true, + install: false, + projectName: 'test', + typescript: true, + spinner: () => ({ + start: () => {}, + stop: () => {}, + }), + } as unknown as Options) + environment.finishRun() + + expect(output.commands).toEqual([]) + }) +})