feat: make results directory output optional (#107)

Add -o, --output-dir option to both client and server commands.
By default, no results directory is created - only console output.
When -o is specified, results are saved to that directory with
timestamped subdirectories.

This eliminates the need to add 'results/' to .gitignore in every
repo where conformance tests are run.

Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 0
Claude-Permission-Prompts: 2
Claude-Escapes: 0
This commit is contained in:
Paul Carleton 2026-01-14 20:16:28 +00:00 • committed by GitHub
commit 62875097f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2,7 +2,7 @@ import { promises as fs } from 'fs';
import path from 'path';
import { ConformanceCheck } from '../types';
import { getClientScenario } from '../scenarios';
import { ensureResultsDir, createResultDir, formatPrettyChecks } from './utils';
import { createResultDir, formatPrettyChecks } from './utils';
/**
* Format markdown-style text for terminal output using ANSI codes
@ -19,15 +19,19 @@ function formatMarkdown(text: string): string {
export async function runServerConformanceTest(
serverUrl: string,
scenarioName: string
scenarioName: string,
outputDir?: string
): Promise<{
checks: ConformanceCheck[];
resultDir: string;
resultDir?: string;
scenarioDescription: string;
}> {
await ensureResultsDir();
const resultDir = createResultDir(scenarioName, 'server');
await fs.mkdir(resultDir, { recursive: true });
let resultDir: string | undefined;
if (outputDir) {
resultDir = createResultDir(outputDir, scenarioName, 'server');
await fs.mkdir(resultDir, { recursive: true });
}
// Scenario is guaranteed to exist by CLI validation
const scenario = getClientScenario(scenarioName)!;
@ -38,12 +42,14 @@ export async function runServerConformanceTest(
const checks = await scenario.run(serverUrl);
await fs.writeFile(
path.join(resultDir, 'checks.json'),
JSON.stringify(checks, null, 2)
);
if (resultDir) {
await fs.writeFile(
path.join(resultDir, 'checks.json'),
JSON.stringify(checks, null, 2)
);
console.log(`Results saved to ${resultDir}`);
console.log(`Results saved to ${resultDir}`);
}
return {
checks,