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({ 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([]) + }) +})