Prefer AGENTS.md over CLAUDE.md for project instructions (#439)
* Prefer AGENTS.md over CLAUDE.md for project instructions * fix: preserve CLAUDE.md fallback behavior * fix: isolate onboarding tests and preserve legacy init * fix: restore full fsOperations exports in test mock and align compact cwd * Fix onboarding test isolation and init migration guidance * Tighten init prompt coverage and onboarding copy * Handle nested project instruction paths consistently * Fix NEW_INIT feature gate for Bun build --------- Co-authored-by: 赵小落 <zhaoxiaoluo@zhaoxiaoluodeMac-mini.local> Co-authored-by: zhaomo01 <zhaomo01@baidu.com>
This commit is contained in:
105
src/utils/projectInstructions.test.ts
Normal file
105
src/utils/projectInstructions.test.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
import { join } from 'node:path'
|
||||
|
||||
import {
|
||||
findProjectInstructionFilePathInAncestors,
|
||||
FALLBACK_PROJECT_INSTRUCTION_FILE,
|
||||
getProjectInstructionFilePath,
|
||||
getProjectInstructionFilePaths,
|
||||
hasProjectInstructionFile,
|
||||
isProjectInstructionFileName,
|
||||
PRIMARY_PROJECT_INSTRUCTION_FILE,
|
||||
} from './projectInstructions.js'
|
||||
|
||||
describe('projectInstructions', () => {
|
||||
test('prefers AGENTS.md over CLAUDE.md for root project instructions', () => {
|
||||
const dir = '/repo'
|
||||
const existingPaths = new Set([
|
||||
join(dir, PRIMARY_PROJECT_INSTRUCTION_FILE),
|
||||
join(dir, FALLBACK_PROJECT_INSTRUCTION_FILE),
|
||||
])
|
||||
|
||||
const filePath = getProjectInstructionFilePath(
|
||||
dir,
|
||||
path => existingPaths.has(path),
|
||||
)
|
||||
|
||||
expect(filePath).toBe(join(dir, PRIMARY_PROJECT_INSTRUCTION_FILE))
|
||||
})
|
||||
|
||||
test('falls back to CLAUDE.md when AGENTS.md is absent', () => {
|
||||
const dir = '/repo'
|
||||
const existingPaths = new Set([join(dir, FALLBACK_PROJECT_INSTRUCTION_FILE)])
|
||||
|
||||
const filePath = getProjectInstructionFilePath(
|
||||
dir,
|
||||
path => existingPaths.has(path),
|
||||
)
|
||||
|
||||
expect(filePath).toBe(join(dir, FALLBACK_PROJECT_INSTRUCTION_FILE))
|
||||
})
|
||||
|
||||
test('returns both candidate root instruction paths', () => {
|
||||
const dir = '/repo'
|
||||
|
||||
expect(getProjectInstructionFilePaths(dir)).toEqual([
|
||||
join(dir, PRIMARY_PROJECT_INSTRUCTION_FILE),
|
||||
join(dir, FALLBACK_PROJECT_INSTRUCTION_FILE),
|
||||
])
|
||||
})
|
||||
|
||||
test('detects whether a repo instruction file exists', () => {
|
||||
const dir = '/repo'
|
||||
const existingPaths = new Set([join(dir, PRIMARY_PROJECT_INSTRUCTION_FILE)])
|
||||
|
||||
expect(hasProjectInstructionFile(dir, path => existingPaths.has(path))).toBe(
|
||||
true,
|
||||
)
|
||||
expect(hasProjectInstructionFile(dir, () => false)).toBe(false)
|
||||
})
|
||||
|
||||
test('recognizes AGENTS.md as a root instruction filename', () => {
|
||||
expect(isProjectInstructionFileName(PRIMARY_PROJECT_INSTRUCTION_FILE)).toBe(
|
||||
true,
|
||||
)
|
||||
expect(isProjectInstructionFileName(FALLBACK_PROJECT_INSTRUCTION_FILE)).toBe(
|
||||
true,
|
||||
)
|
||||
expect(isProjectInstructionFileName('README.md')).toBe(false)
|
||||
})
|
||||
|
||||
test('finds repo instructions in ancestor directories', () => {
|
||||
const repoDir = '/repo'
|
||||
const nestedDir = join(repoDir, 'packages', 'app')
|
||||
const existingPaths = new Set([join(repoDir, PRIMARY_PROJECT_INSTRUCTION_FILE)])
|
||||
|
||||
expect(
|
||||
findProjectInstructionFilePathInAncestors(
|
||||
nestedDir,
|
||||
path => existingPaths.has(path),
|
||||
),
|
||||
).toBe(join(repoDir, PRIMARY_PROJECT_INSTRUCTION_FILE))
|
||||
})
|
||||
|
||||
test('prefers the closest ancestor project instruction file', () => {
|
||||
const repoDir = '/repo'
|
||||
const nestedProjectDir = join(repoDir, 'packages', 'app')
|
||||
const existingPaths = new Set([
|
||||
join(repoDir, PRIMARY_PROJECT_INSTRUCTION_FILE),
|
||||
join(nestedProjectDir, FALLBACK_PROJECT_INSTRUCTION_FILE),
|
||||
])
|
||||
|
||||
expect(
|
||||
findProjectInstructionFilePathInAncestors(
|
||||
join(nestedProjectDir, 'src'),
|
||||
path => existingPaths.has(path),
|
||||
),
|
||||
).toBe(join(nestedProjectDir, FALLBACK_PROJECT_INSTRUCTION_FILE))
|
||||
})
|
||||
|
||||
test('returns null when no ancestor repo instruction file exists', () => {
|
||||
expect(
|
||||
findProjectInstructionFilePathInAncestors('/repo/packages/app', () => false),
|
||||
).toBeNull()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user