fix(fs-local): degrade basis I/O failures to null

Descriptor-phase errnos in readTextForDiff fold to before: null so a file
deleted or made unreadable after the caller's preflight cannot fail the
committed write; cancellation and non-errno faults still propagate. Drops
the now-covered isFile v8 ignore, extends llm-replay with catalog
capability parity (defaultMaxTokens/reasoningEfforts), and records the
fs-write-overwrite-bounded keyless snapshot pinning the over-limit
whole-file fallback through the real acp-agent composition.
This commit is contained in:
ZiyaZhang
2026-08-08 11:49:42 -07:00
parent 3f3c8e31e9
commit 9a299f9827
13 changed files with 281 additions and 43 deletions
+58
View File
@@ -398,6 +398,64 @@ describe('readTextForDiff', () => {
}
})
it('returns null when the file vanishes before the basis open (deletion race)', async () => {
expect(await readTextForDiff(join(dir, 'deleted-after-preflight.txt'), 32)).toBeNull()
})
it('returns null when the opened descriptor is no longer a regular file', async () => {
const file = join(dir, 'swapped.txt')
await writeFile(file, 'abcdef')
vi.resetModules()
vi.doMock('node:fs/promises', async (importOriginal) => {
const actual = await importOriginal<typeof import('node:fs/promises')>()
return {
...actual,
async open(...args: Parameters<typeof actual.open>) {
const handle = await actual.open(...args)
return {
close: handle.close.bind(handle),
read: handle.read.bind(handle),
async stat(...statArgs: Parameters<typeof handle.stat>) {
const info = await handle.stat(...statArgs)
return Object.assign(info, { isFile: () => false })
},
}
},
}
})
try {
const { readTextForDiff: isolatedReadTextForDiff } = await import('../src/fsio.ts')
expect(await isolatedReadTextForDiff(file, 32)).toBeNull()
} finally {
vi.doUnmock('node:fs/promises')
vi.resetModules()
}
})
it('propagates a non-errno fault instead of masking it as a null basis', async () => {
const file = join(dir, 'faulted.txt')
await writeFile(file, 'abcdef')
vi.resetModules()
vi.doMock('node:fs/promises', async (importOriginal) => {
const actual = await importOriginal<typeof import('node:fs/promises')>()
return {
...actual,
async open() {
throw new TypeError('forged programming fault')
},
}
})
try {
const { readTextForDiff: isolatedReadTextForDiff } = await import('../src/fsio.ts')
await expect(isolatedReadTextForDiff(file, 32)).rejects.toThrow('forged programming fault')
} finally {
vi.doUnmock('node:fs/promises')
vi.resetModules()
}
})
it('returns null for binary and invalid UTF-8 without blocking the caller write', async () => {
await writeFile(join(dir, 'bin'), Buffer.from([0x68, 0x00, 0x69]))
await writeFile(join(dir, 'bad'), Buffer.from([0x68, 0xff, 0x69]))