Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 32 additions & 25 deletions packages/wbfy/src/fixers/playwrightConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -30,32 +31,33 @@ const asObject = (properties: Record<string, ParsedValue>, 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<string, ParsedValue>, extraMembers: string[] = []): ParsedObject {
return {
Expand Down Expand Up @@ -83,8 +85,8 @@ export async function fixPlaywrightConfig(config: PackageConfig): Promise<void>
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);
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions packages/wbfy/src/generators/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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}) <agent@willbooster.com>\`` : ''}.
- 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)}
`
Expand Down
4 changes: 4 additions & 0 deletions packages/wbfy/src/utils/packageCapabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<PackageConfig, 'isBun'>): 'bun' | 'yarn' {
return config.isBun ? 'bun' : 'yarn';
}
2 changes: 1 addition & 1 deletion packages/wbfy/test/agentInstructions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading