diff --git a/packages/wbfy/src/fixers/playwrightConfig.ts b/packages/wbfy/src/fixers/playwrightConfig.ts index 95a66b14..686a7b27 100644 --- a/packages/wbfy/src/fixers/playwrightConfig.ts +++ b/packages/wbfy/src/fixers/playwrightConfig.ts @@ -6,6 +6,7 @@ import ts from 'typescript'; import { logger } from '../logger.js'; import type { PackageConfig } from '../packageConfig.js'; import { fsUtil } from '../utils/fsUtil.js'; +import { getPackageManagerCommand } from '../utils/packageCapabilities.js'; import { promisePool } from '../utils/promisePool.js'; type ParsedValue = @@ -30,32 +31,33 @@ const asObject = (properties: Record, extraMembers: string[ value: toParsedObject(properties, extraMembers), }); -const defaultConfig = toParsedObject({ - forbidOnly: literal('!!process.env.CI'), - retries: literal('process.env.PWDEBUG ? 0 : process.env.CI ? 5 : 1'), - use: asObject({ - baseURL: literal('process.env.NEXT_PUBLIC_BASE_URL'), - trace: literal("process.env.CI ? 'on-first-retry' : 'retain-on-failure'"), - screenshot: literal("process.env.CI ? 'only-on-failure' : 'on'"), - video: literal("process.env.CI ? 'on-first-retry' : 'retain-on-failure'"), - }), - webServer: asObject({ - command: literal("'wb start --mode test'"), - url: literal('process.env.NEXT_PUBLIC_BASE_URL'), - reuseExistingServer: literal('!!process.env.CI'), - timeout: literal('300_000'), - stdout: literal("'pipe'"), - stderr: literal("'pipe'"), - env: literal(`{ +const createDefaultConfig = (config: PackageConfig): ParsedObject => + toParsedObject({ + forbidOnly: literal('!!process.env.CI'), + retries: literal('process.env.PWDEBUG ? 0 : process.env.CI ? 5 : 1'), + use: asObject({ + baseURL: literal('process.env.NEXT_PUBLIC_BASE_URL'), + trace: literal("process.env.CI ? 'on-first-retry' : 'retain-on-failure'"), + screenshot: literal("process.env.CI ? 'only-on-failure' : 'on'"), + video: literal("process.env.CI ? 'on-first-retry' : 'retain-on-failure'"), + }), + webServer: asObject({ + command: literal(getWbStartTestCommand(config)), + url: literal('process.env.NEXT_PUBLIC_BASE_URL'), + reuseExistingServer: literal('!!process.env.CI'), + timeout: literal('300_000'), + stdout: literal("'pipe'"), + stderr: literal("'pipe'"), + env: literal(`{ ...process.env, PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION: 'true', }`), - gracefulShutdown: literal(`{ + gracefulShutdown: literal(`{ signal: 'SIGTERM', timeout: 500, }`), - }), -}); + }), + }); function toParsedObject(properties: Record, extraMembers: string[] = []): ParsedObject { return { @@ -83,8 +85,8 @@ export async function fixPlaywrightConfig(config: PackageConfig): Promise if (!parsed) return; // Keep filling missing defaults, but don't overwrite local adjustments on every regeneration. - const merged = mergeParsedObjects(defaultConfig, parsed); - setWebServerCommand(merged); + const merged = mergeParsedObjects(createDefaultConfig(config), parsed); + setWebServerCommand(merged, config); const newObjectLiteral = stringifyValue({ kind: 'object', value: merged }, 0); const start = extractedObjectLiteral.node.getStart(extractedObjectLiteral.source); @@ -153,13 +155,18 @@ function getEnvFilePaths(dirPath: string): string[] { return envFilePaths; } -function setWebServerCommand(object: ParsedObject): void { +function setWebServerCommand(object: ParsedObject, config: PackageConfig): void { const webServer = object.properties.webServer; if (webServer?.kind !== 'object') return; // wb owns the canonical test-server startup path; keep custom Playwright - // server settings while normalizing the command itself. - webServer.value.properties.command = literal("'wb start --mode test'"); + // server settings while normalizing the command itself. Invoke wb through the + // package manager because target repos install wb as a package dependency. + webServer.value.properties.command = literal(getWbStartTestCommand(config)); +} + +function getWbStartTestCommand(config: PackageConfig): string { + return `'${getPackageManagerCommand(config)} wb start --mode test'`; } function extractDefineConfigObjectLiteral(content: string): ExtractedObjectLiteral | undefined { diff --git a/packages/wbfy/src/generators/agents.ts b/packages/wbfy/src/generators/agents.ts index 0614c231..ebab3e01 100644 --- a/packages/wbfy/src/generators/agents.ts +++ b/packages/wbfy/src/generators/agents.ts @@ -3,6 +3,7 @@ import path from 'node:path'; import { logger } from '../logger.js'; import type { PackageConfig } from '../packageConfig.js'; import { fsUtil } from '../utils/fsUtil.js'; +import { getPackageManagerCommand } from '../utils/packageCapabilities.js'; import { promisePool } from '../utils/promisePool.js'; export async function generateAgentInstructions(rootConfig: PackageConfig, allConfigs: PackageConfig[]): Promise { @@ -45,7 +46,7 @@ function generateAgentInstruction( toolName: string, extraContent?: string ): string { - const packageManager = rootConfig.isBun ? 'bun' : 'yarn'; + const packageManager = getPackageManagerCommand(rootConfig); const baseContent = ` ## Project Information @@ -74,7 +75,7 @@ function generateAgentInstruction( - If not specified, make sure to add a new line at the end of your commit message${rootConfig.isWillBoosterRepo ? ` with: \`Co-authored-by: WillBooster (${toolName}) \`` : ''}. - Always create new commits. Avoid using \`--amend\`. - Always use heredoc syntax when passing multi-line content to any command. -${hasPlaywrightTestServer(allConfigs) ? `- Use \`wb start --mode test\` to launch a web server for debugging or testing.` : ''} +${hasPlaywrightTestServer(allConfigs) ? `- Use \`${packageManager} wb start --mode test\` to launch a web server for debugging or testing.` : ''} ${generateAgentCodingStyle(allConfigs)} ` diff --git a/packages/wbfy/src/utils/packageCapabilities.ts b/packages/wbfy/src/utils/packageCapabilities.ts index 68e2b125..3f5f00a5 100644 --- a/packages/wbfy/src/utils/packageCapabilities.ts +++ b/packages/wbfy/src/utils/packageCapabilities.ts @@ -12,3 +12,7 @@ export function doesContainJsOrTs(config: PackageConfig): boolean { export function doesContainJava(config: PackageConfig): boolean { return config.doesContainJava || config.doesContainJavaInPackages; } + +export function getPackageManagerCommand(config: Pick): 'bun' | 'yarn' { + return config.isBun ? 'bun' : 'yarn'; +} diff --git a/packages/wbfy/test/agentInstructions.test.ts b/packages/wbfy/test/agentInstructions.test.ts index 498d427b..708cf075 100644 --- a/packages/wbfy/test/agentInstructions.test.ts +++ b/packages/wbfy/test/agentInstructions.test.ts @@ -35,7 +35,7 @@ test('mentions wb test server startup for Playwright projects on the first run', await promisePool.promiseAll(); const content = await fs.promises.readFile(path.join(dirPath, 'AGENTS.md'), 'utf8'); - expect(content).toContain('Use `wb start --mode test` to launch a web server for debugging or testing.'); + expect(content).toContain('Use `bun wb start --mode test` to launch a web server for debugging or testing.'); }); function createTempDir(): string {