/** * @jest-environment node */ import fs from 'node:fs'; import { spawnSync } from 'node:child_process'; import os from 'node:os'; import path from 'node:path'; import { createHash } from 'node:crypto'; import YAML from 'yaml'; import { loadStartPreparationFleetSettings } from './src/adapter/entry-points/cli/fleetConfig'; const readmeText = fs.readFileSync(path.join(__dirname, 'README.md'), 'utf8'); const nextSectionHeadingPattern = /^#{2,3} /m; const extractExampleYamlBlockText = ( markdown: string, sectionHeading: string, ): string => { const headingIndex = markdown.indexOf(sectionHeading); if (headingIndex === -1) { throw new Error( `Section heading not found in README.md: ${sectionHeading}`, ); } const afterHeading = markdown.slice(headingIndex + sectionHeading.length); const nextHeadingMatch = afterHeading.match(nextSectionHeadingPattern); const sectionBody = nextHeadingMatch ? afterHeading.slice(0, nextHeadingMatch.index) : afterHeading; const exampleLabelIndex = sectionBody.indexOf('Example:'); if (exampleLabelIndex === -1) { throw new Error( `"Example:" line not found within section: ${sectionHeading}`, ); } const afterExampleLabel = sectionBody.slice(exampleLabelIndex); const fencedYamlBlockMatch = afterExampleLabel.match( /```yaml\n([\s\S]*?)\n```/, ); if (!fencedYamlBlockMatch) { throw new Error( `Fenced \`\`\`yaml block not found after "Example:" within section: ${sectionHeading}`, ); } return fencedYamlBlockMatch[1]; }; const parseExampleYamlBlock = ( sectionHeading: string, ): Record => { const yamlBlockText = extractExampleYamlBlockText(readmeText, sectionHeading); return YAML.parse(yamlBlockText) as Record; }; const extractMapExampleYamlBlockText = (markdown: string): string => { const label = 'Example with the map:'; const lines = markdown.split('\n'); const labelIndex = lines.findIndex((line) => line === label); if (labelIndex === -1) { throw new Error(`README.md label not found: ${label}`); } let openingFenceIndex = labelIndex + 1; while ( openingFenceIndex < lines.length && lines[openingFenceIndex].trim() === '' ) { openingFenceIndex += 1; } if (lines[openingFenceIndex] !== '```yaml') { throw new Error(`YAML opening fence not found after: ${label}`); } const closingFenceIndex = lines.findIndex( (line, index) => index > openingFenceIndex && line === '```', ); if (closingFenceIndex === -1) { throw new Error(`YAML closing fence not found after: ${label}`); } return lines.slice(openingFenceIndex + 1, closingFenceIndex).join('\n'); }; describe('README.md Example YAML blocks document agentDefinitionsDirectoryPath', () => { test.each<{ sectionHeading: string; isNested: boolean }>([ { sectionHeading: '### Schedule Command Config', isNested: true }, { sectionHeading: '### startDaemon and notifyFinishedIssuePreparation Commands Config', isNested: false, }, ])( 'the "$sectionHeading" Example YAML block declares a non-empty agentDefinitionsDirectoryPath, following the awLogDirectoryPath pattern', ({ sectionHeading, isNested }) => { const parsedExample = parseExampleYamlBlock(sectionHeading); const configRoot = isNested ? (parsedExample.startPreparation as Record | undefined) : parsedExample; expect(typeof configRoot?.awLogDirectoryPath).toBe('string'); expect((configRoot?.awLogDirectoryPath as string).length).toBeGreaterThan( 0, ); expect(typeof configRoot?.agentDefinitionsDirectoryPath).toBe('string'); expect( (configRoot?.agentDefinitionsDirectoryPath as string).length, ).toBeGreaterThan(0); }, ); }); test('README.md llmModelNameByAgentName map example is accepted by the fleet reader', () => { const temporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-llm-model-map-'), ); const fleetConfigFilePath = path.join( temporaryDirectory, 'fleet-config.yaml', ); try { const yamlBlockText = extractMapExampleYamlBlockText(readmeText); fs.writeFileSync(fleetConfigFilePath, yamlBlockText); const settings = loadStartPreparationFleetSettings(fleetConfigFilePath); const modelMap = settings.llmModelNameByAgentName; expect(modelMap).not.toBeNull(); expect(Object.keys(modelMap ?? {}).length).toBeGreaterThan(0); } finally { fs.rmSync(temporaryDirectory, { force: true, recursive: true }); } }); test('README.md llmModelNameByAgentName map deletion reports the missing label', () => { const readmeFilePath = path.join(__dirname, 'README.md'); const temporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-map-deletion-'), ); const cacheDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-map-deletion-cache-'), ); const originalReadme = fs.readFileSync(readmeFilePath, 'utf8'); const lines = originalReadme.split('\n'); const label = 'Example with the map:'; const labelIndex = lines.findIndex((line) => line === label); const openingFenceIndex = lines.findIndex( (line, index) => index > labelIndex && line === '```yaml', ); const closingFenceIndex = lines.findIndex( (line, index) => index > openingFenceIndex && line === '```', ); const mutatedReadme = [ ...lines.slice(0, labelIndex), ...lines.slice(closingFenceIndex + 1), ].join('\n'); try { fs.writeFileSync(readmeFilePath, mutatedReadme); const subprocess = spawnSync( 'npm', [ 'run', 'test', '--', '--coverage=false', '--reporters=default', '--runInBand', '--runTestsByPath', 'README.test.ts', '--testNamePattern', '^README\\.md llmModelNameByAgentName map example is accepted by the fleet reader$', `--cacheDirectory=${cacheDirectory}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: temporaryDirectory }, }, ); const failureOutput = [subprocess.stdout, subprocess.stderr] .filter((output): output is string => typeof output === 'string') .join('\n'); const missingLabel = /README\.md label not found: (Example with the map:)/.exec( failureOutput, )?.[1] ?? null; expect(missingLabel).toBe('Example with the map:'); expect( fs .readdirSync(temporaryDirectory) .filter((entryName) => entryName !== 'node-compile-cache'), ).toEqual([]); } finally { fs.writeFileSync(readmeFilePath, originalReadme); fs.rmSync(temporaryDirectory, { force: true, recursive: true }); fs.rmSync(cacheDirectory, { force: true, recursive: true }); } }); const snapshotRepositoryFiles = (): string => { const generatedReadmeTestArtifactPattern = /^\.readme-cleanup-sandbox-/; const hashRegularFile = (filePath: string): string => { const hash = createHash('sha256'); const fileDescriptor = fs.openSync(filePath, 'r'); const buffer = Buffer.allocUnsafe(64 * 1024); try { let bytesRead = buffer.length; while (bytesRead > 0) { bytesRead = fs.readSync(fileDescriptor, buffer, 0, buffer.length, null); if (bytesRead > 0) { hash.update(buffer.subarray(0, bytesRead)); } } } finally { fs.closeSync(fileDescriptor); } return hash.digest('hex'); }; const snapshotHash = createHash('sha256'); const directoriesToVisit = [__dirname]; const rootStat = fs.lstatSync(__dirname); snapshotHash.update( `${JSON.stringify({ path: '.', type: 'directory', permissions: (rootStat.mode & 0o7777).toString(8).padStart(4, '0'), symlinkTarget: '', digest: '', })}\n`, ); while (directoriesToVisit.length > 0) { const directoryPath = directoriesToVisit.pop(); if (directoryPath === undefined) { break; } const directoryEntries = fs .readdirSync(directoryPath, { withFileTypes: true }) .sort((left, right) => (left.name < right.name ? -1 : 1)); for (const directoryEntry of directoryEntries) { if (generatedReadmeTestArtifactPattern.test(directoryEntry.name)) { continue; } const entryPath = path.join(directoryPath, directoryEntry.name); const relativePath = path .relative(__dirname, entryPath) .split(path.sep) .join('/'); if (relativePath === 'reports') { continue; } if (relativePath.split('/').includes('.git')) { continue; } if (relativePath.split('/').includes('node_modules')) { continue; } const entryStat = fs.lstatSync(entryPath); const entryType = entryStat.isDirectory() ? 'directory' : entryStat.isFile() ? 'regular' : entryStat.isSymbolicLink() ? 'symlink' : entryStat.isFIFO() ? 'fifo' : entryStat.isSocket() ? 'socket' : entryStat.isBlockDevice() ? 'block-device' : entryStat.isCharacterDevice() ? 'character-device' : 'unknown'; snapshotHash.update( `${JSON.stringify({ path: relativePath, type: entryType, permissions: (entryStat.mode & 0o7777).toString(8).padStart(4, '0'), symlinkTarget: entryStat.isSymbolicLink() ? fs.readlinkSync(entryPath) : '', digest: entryStat.isFile() ? hashRegularFile(entryPath) : '', })}\n`, ); if (entryStat.isDirectory()) { directoriesToVisit.push(entryPath); } } } return snapshotHash.digest('hex'); }; test('README.md llmModelNameByAgentName repository snapshot ignores generated README cleanup artifacts', () => { const generatedArtifactDirectory = fs.mkdtempSync( path.join(__dirname, '.readme-cleanup-sandbox-'), ); try { const beforeSnapshot = snapshotRepositoryFiles(); fs.writeFileSync( path.join(generatedArtifactDirectory, 'generated-test-artifact.txt'), 'generated during the README test run', ); expect(snapshotRepositoryFiles()).toBe(beforeSnapshot); } finally { fs.rmSync(generatedArtifactDirectory, { force: true, recursive: true }); } }); test('README.md llmModelNameByAgentName repository snapshot ignores generated test reports', () => { const reportsDirectory = path.join(__dirname, 'reports'); const reportsDirectoryExisted = fs.existsSync(reportsDirectory); fs.mkdirSync(reportsDirectory, { recursive: true }); const generatedReportDirectory = fs.mkdtempSync( path.join(reportsDirectory, 'readme-snapshot-report-'), ); try { const beforeSnapshot = snapshotRepositoryFiles(); fs.writeFileSync( path.join(generatedReportDirectory, 'generated-report.txt'), 'generated during the test run', ); expect(snapshotRepositoryFiles()).toBe(beforeSnapshot); } finally { fs.rmSync(generatedReportDirectory, { force: true, recursive: true }); if (!reportsDirectoryExisted) { fs.rmSync(reportsDirectory, { force: true, recursive: true }); } } }); test('README.md llmModelNameByAgentName repository snapshot detects arbitrary repository file changes', () => { const sourceChangeDirectory = fs.mkdtempSync( path.join(__dirname, 'readme-snapshot-source-'), ); try { const beforeSnapshot = snapshotRepositoryFiles(); fs.writeFileSync( path.join(sourceChangeDirectory, 'source-change.txt'), 'arbitrary repository change', ); expect(snapshotRepositoryFiles()).not.toBe(beforeSnapshot); } finally { fs.rmSync(sourceChangeDirectory, { force: true, recursive: true }); } }); test('README.md llmModelNameByAgentName test leaves no repository file changes after existing README tests run', () => { const temporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-working-tree-test-'), ); const jestCacheDirectory = path.join(temporaryDirectory, 'jest-cache'); const resultFilePath = path.join(temporaryDirectory, 'result.json'); try { const beforeSnapshot = snapshotRepositoryFiles(); const childResult = spawnSync( 'npx', [ 'jest', 'README.test.ts', '--selectProjects', 'backend', '--coverage=false', '--runInBand', '--reporters=default', '--testNamePattern', '^README\\.md llmModelNameByAgentName map example is accepted by the fleet reader$', `--cacheDirectory=${jestCacheDirectory}`, '--json', `--outputFile=${resultFilePath}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: temporaryDirectory, }, timeout: 60000, }, ); if (childResult.error) { throw childResult.error; } if (childResult.status !== 0) { throw new Error(childResult.stderr); } const afterSnapshot = snapshotRepositoryFiles(); expect(afterSnapshot).toEqual(beforeSnapshot); } finally { fs.rmSync(temporaryDirectory, { force: true, recursive: true }); } }); test.each([ { name: 'reader returns', expectedExitCode: 0 }, { name: 'reader throws', expectedExitCode: 1 }, ])( 'README.md llmModelNameByAgentName map example leaves no temporary files when the $name', ({ name, expectedExitCode }) => { const sandboxDirectory = fs.mkdtempSync( path.join(__dirname, '.readme-cleanup-sandbox-'), ); const temporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-cleanup-temp-'), ); const cacheDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-cleanup-cache-'), ); try { fs.copyFileSync( __filename, path.join(sandboxDirectory, 'README.test.ts'), ); const sandboxReadmePath = path.join(sandboxDirectory, 'README.md'); fs.copyFileSync(path.join(__dirname, 'README.md'), sandboxReadmePath); fs.symlinkSync( path.join(__dirname, 'src'), path.join(sandboxDirectory, 'src'), 'dir', ); if (name === 'reader throws') { const readmeWithInvalidModelName = fs .readFileSync(sandboxReadmePath, 'utf8') .replace(" developer: 'gpt-5.6-luna'", " developer: ''"); fs.writeFileSync(sandboxReadmePath, readmeWithInvalidModelName); } const result = spawnSync( 'npx', [ 'jest', path.join(sandboxDirectory, 'README.test.ts'), '--selectProjects', 'backend', '--coverage=false', '--runInBand', '--reporters=default', '--testNamePattern', '^README\\.md llmModelNameByAgentName map example is accepted by the fleet reader$', `--cacheDirectory=${cacheDirectory}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: temporaryDirectory, }, timeout: 120000, }, ); expect(result.error).toBeUndefined(); expect(result.status).toBe(expectedExitCode); expect( fs .readdirSync(temporaryDirectory) .filter((entryName) => entryName !== 'node-compile-cache'), ).toEqual([]); } finally { fs.rmSync(sandboxDirectory, { force: true, recursive: true }); fs.rmSync(temporaryDirectory, { force: true, recursive: true }); fs.rmSync(cacheDirectory, { force: true, recursive: true }); } }, ); test('README.md llmModelNameByAgentName map example reports its label when the opening fence is deleted', () => { const readmeFilePath = path.join(__dirname, 'README.md'); const temporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-fence-deletion-'), ); const cacheDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-fence-deletion-cache-'), ); const originalReadme = fs.readFileSync(readmeFilePath, 'utf8'); const lines = originalReadme.split('\n'); const label = 'Example with the map:'; const labelIndex = lines.findIndex((line) => line === label); const openingFenceIndex = lines.findIndex( (line, index) => index > labelIndex && line === '```yaml', ); const mutatedReadme = [ ...lines.slice(0, openingFenceIndex), ...lines.slice(openingFenceIndex + 1), ].join('\n'); try { fs.writeFileSync(readmeFilePath, mutatedReadme); const subprocess = spawnSync( 'npm', [ 'run', 'test', '--', '--coverage=false', '--reporters=default', '--runInBand', '--runTestsByPath', 'README.test.ts', '--testNamePattern', '^README\\.md llmModelNameByAgentName map example is accepted by the fleet reader$', `--cacheDirectory=${cacheDirectory}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: temporaryDirectory }, }, ); const failureOutput = [subprocess.stdout, subprocess.stderr] .filter((output): output is string => typeof output === 'string') .join('\n'); const missingLabel = /YAML opening fence not found after: (Example with the map:)/.exec( failureOutput, )?.[1] ?? null; expect(typeof subprocess.status).toBe('number'); expect(subprocess.status).not.toBe(0); expect(missingLabel).toBe('Example with the map:'); expect( fs .readdirSync(temporaryDirectory) .filter((entryName) => entryName !== 'node-compile-cache'), ).toEqual([]); } finally { fs.writeFileSync(readmeFilePath, originalReadme); fs.rmSync(temporaryDirectory, { force: true, recursive: true }); fs.rmSync(cacheDirectory, { force: true, recursive: true }); } }); test('README.md llmModelNameByAgentName added cases pass with only the map example', () => { const readmeFilePath = path.join(__dirname, 'README.md'); const originalReadme = fs.readFileSync(readmeFilePath, 'utf8'); const lines = originalReadme.split('\n'); const labelIndex = lines.findIndex( (line) => line === 'Example with the map:', ); const openingFenceIndex = lines.findIndex( (line, index) => index > labelIndex && line === '```yaml', ); const closingFenceIndex = lines.findIndex( (line, index) => index > openingFenceIndex && line === '```', ); const childTemporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-meta-minimal-'), ); const childCacheDirectory = path.join(childTemporaryDirectory, 'jest-cache'); const resultFilePath = path.join(childTemporaryDirectory, 'result.json'); const minimalReadme = [ ...lines.slice(labelIndex, closingFenceIndex + 1), ].join('\n'); try { fs.writeFileSync(readmeFilePath, minimalReadme); const result = spawnSync( 'npx', [ 'jest', 'README.test.ts', '--selectProjects', 'backend', '--coverage=false', '--runInBand', '--reporters=default', '--testNamePattern', '^README\\.md llmModelNameByAgentName test leaves no repository file changes after existing README tests run$', `--cacheDirectory=${childCacheDirectory}`, '--json', `--outputFile=${resultFilePath}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: childTemporaryDirectory, }, timeout: 120000, }, ); expect(result.error).toBeUndefined(); expect(result.status).toBe(0); } finally { fs.writeFileSync(readmeFilePath, originalReadme); fs.rmSync(childTemporaryDirectory, { force: true, recursive: true }); } }); test('README.md llmModelNameByAgentName added cases delete temporary files', () => { const childTemporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-meta-cleanup-'), ); const resultDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-meta-result-'), ); const childCacheDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-meta-cleanup-cache-'), ); const resultFilePath = path.join(resultDirectory, 'result.json'); try { const result = spawnSync( 'npx', [ 'jest', 'README.test.ts', '--selectProjects', 'backend', '--coverage=false', '--runInBand', '--reporters=default', '--testNamePattern', 'README\\.md llmModelNameByAgentName (map deletion reports the missing label|map example reports its label when the opening fence is deleted)', `--cacheDirectory=${childCacheDirectory}`, '--json', `--outputFile=${resultFilePath}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: childTemporaryDirectory, }, timeout: 120000, }, ); expect(result.error).toBeUndefined(); expect(result.status).toBe(0); expect( fs .readdirSync(childTemporaryDirectory) .filter((entryName) => entryName !== 'node-compile-cache'), ).toEqual([]); } finally { fs.rmSync(childTemporaryDirectory, { force: true, recursive: true }); fs.rmSync(resultDirectory, { force: true, recursive: true }); fs.rmSync(childCacheDirectory, { force: true, recursive: true }); } }); test('README.md llmModelNameByAgentName added case titles identify every added case', () => { const childTemporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-meta-titles-'), ); const resultFilePath = path.join(childTemporaryDirectory, 'result.json'); try { const result = spawnSync( 'npx', [ 'jest', 'README.test.ts', '--selectProjects', 'backend', '--coverage=false', '--runInBand', '--reporters=default', '--testNamePattern', '^(?!.*(?:added case(?:s)? (pass with only the map example|delete temporary files|titles identify every added case)|every added case passes with only the map example$)).*', '--json', `--outputFile=${resultFilePath}`, `--cacheDirectory=${path.join(childTemporaryDirectory, 'jest-cache')}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: childTemporaryDirectory, }, }, ); expect(result.error).toBeUndefined(); expect(result.status).toBe(0); const testResults = JSON.parse(fs.readFileSync(resultFilePath, 'utf8')) .testResults as Array<{ assertionResults: Array<{ title: string; status: string }>; }>; const allCaseResults = testResults.flatMap( ({ assertionResults }) => assertionResults, ); const metaCaseTitlePattern = /added case(?:s)? (pass with only the map example|delete temporary files|titles identify every added case)|every added case passes with only the map example/; const caseResults = allCaseResults.filter( ({ title }) => !metaCaseTitlePattern.test(title), ); const existingCaseResults = caseResults.filter( ({ title }) => !title.includes('llmModelNameByAgentName'), ); const addedCaseResults = caseResults.filter(({ title }) => title.includes('llmModelNameByAgentName'), ); expect(existingCaseResults).toHaveLength(2); expect(caseResults).toHaveLength(2 + addedCaseResults.length); expect(addedCaseResults.every(({ status }) => status === 'passed')).toBe( true, ); } finally { fs.rmSync(childTemporaryDirectory, { force: true, recursive: true }); } }); test('README.md llmModelNameByAgentName every added case passes with only the map example', () => { const readmeFilePath = path.join(__dirname, 'README.md'); const originalReadme = fs.readFileSync(readmeFilePath, 'utf8'); const lines = originalReadme.split('\n'); const labelIndex = lines.findIndex( (line) => line === 'Example with the map:', ); const openingFenceIndex = lines.findIndex( (line, index) => index > labelIndex && line === '```yaml', ); const closingFenceIndex = lines.findIndex( (line, index) => index > openingFenceIndex && line === '```', ); const temporaryDirectory = fs.mkdtempSync( path.join(os.tmpdir(), 'readme-all-added-minimal-'), ); const resultFilePath = path.join(temporaryDirectory, 'result.json'); const minimalReadme = lines .slice(labelIndex, closingFenceIndex + 1) .join('\n'); try { fs.writeFileSync(readmeFilePath, minimalReadme); const result = spawnSync( 'npx', [ 'jest', 'README.test.ts', '--selectProjects', 'backend', '--coverage=false', '--runInBand', '--reporters=default', '--testNamePattern', '^(?!.*(?:added cases pass with only the map example|added cases delete temporary files|added case titles identify every added case|every added case passes with only the map example)$).*llmModelNameByAgentName', '--json', `--outputFile=${resultFilePath}`, `--cacheDirectory=${path.join(temporaryDirectory, 'jest-cache')}`, ], { cwd: __dirname, encoding: 'utf8', env: { ...process.env, TMPDIR: temporaryDirectory, }, timeout: 120000, }, ); expect(result.error).toBeUndefined(); expect(result.status).toBe(0); const testResults = JSON.parse(fs.readFileSync(resultFilePath, 'utf8')) .testResults as Array<{ assertionResults: Array<{ title: string; status: string }>; }>; const addedCaseResults = testResults .flatMap(({ assertionResults }) => assertionResults) .filter( ({ title, status }) => title.includes('llmModelNameByAgentName') && status !== 'pending', ); expect(addedCaseResults.length).toBeGreaterThan(0); expect(addedCaseResults.every(({ status }) => status === 'passed')).toBe( true, ); } finally { fs.writeFileSync(readmeFilePath, originalReadme); fs.rmSync(temporaryDirectory, { force: true, recursive: true }); } });