mirror of
https://github.com/anthropics/claude-code.git
synced 2026-10-02 05:25:05 +08:00
fix(agents-md): retain instructions after truncated reads
This commit is contained in:
@@ -223,7 +223,14 @@ export function register(on: On, options: PluginOptions): void {
|
||||
...Files.filesOf(claude),
|
||||
]).filter(file => !sent.has(file.path))
|
||||
const attached = fresh.filter(file => !Frames.isFileAt(file, read))
|
||||
const isWholeRead = e.offset === undefined && e.limit === undefined
|
||||
const output = result.result
|
||||
const isPartialText =
|
||||
output?.type === 'text' &&
|
||||
(output.file.truncatedByTokenCap ||
|
||||
output.file.startLine !== 1 ||
|
||||
output.file.numLines < output.file.totalLines)
|
||||
const isWholeRead =
|
||||
e.offset === undefined && e.limit === undefined && !isPartialText
|
||||
|
||||
for (const file of fresh) {
|
||||
const isSent =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, test, tier } from 'claude-code/testing'
|
||||
import { describe, expect, mock, test, tier } from 'claude-code/testing'
|
||||
|
||||
import Hooks from '../hooks'
|
||||
import Fixtures from './fixtures'
|
||||
@@ -84,6 +84,70 @@ describe('register', () => {
|
||||
).toEqual({ blocks: BLOCKS, instructionFiles: [] })
|
||||
})
|
||||
|
||||
for (const [name, args, file, attaches] of [
|
||||
[
|
||||
'an auto-paginated read',
|
||||
{},
|
||||
{ content: '# head\nfollow', truncatedByTokenCap: true },
|
||||
true,
|
||||
],
|
||||
['an incomplete line range', {}, { content: '# head', numLines: 1 }, true],
|
||||
['a complete read', {}, {}, false],
|
||||
['an explicit limit', { limit: 1 }, { content: '# head', numLines: 1 }, true],
|
||||
[
|
||||
'an explicit offset',
|
||||
{ offset: 2 },
|
||||
{ content: 'follow the tail rule', numLines: 1, startLine: 2 },
|
||||
true,
|
||||
],
|
||||
['an unstructured result', {}, undefined, false],
|
||||
] as const) {
|
||||
test(`a nested AGENTS.md after ${name}`, async ($, on) => {
|
||||
const dir = `${Fixtures.SESSION.cwd}/nested`
|
||||
const path = `${dir}/AGENTS.md`
|
||||
const content = '# head\nfollow the tail rule'
|
||||
const started = Fixtures.projectOf(
|
||||
on,
|
||||
[Fixtures.ancestorOf(dir, 'AGENTS.md', content)],
|
||||
[],
|
||||
)
|
||||
|
||||
mock.env(on, {})
|
||||
on('session.cwd', () => ({ value: Fixtures.SESSION.cwd }))
|
||||
on('tool.call', ($, e) => ({
|
||||
result:
|
||||
e.tool === 'Read' && file !== undefined
|
||||
? {
|
||||
type: 'text',
|
||||
file: Object.assign(
|
||||
{
|
||||
filePath: e.file_path,
|
||||
content,
|
||||
numLines: 2,
|
||||
startLine: 1,
|
||||
totalLines: 2,
|
||||
},
|
||||
file,
|
||||
),
|
||||
}
|
||||
: 'read',
|
||||
}))
|
||||
|
||||
const direct = await $.tool.call({ tool: 'Read', file_path: path, ...args })
|
||||
const source = { tool: 'Read', file_path: `${dir}/source.ts` } as const
|
||||
const after = await $.tool.call(source)
|
||||
const repeated = await $.tool.call(source)
|
||||
|
||||
expect(direct.context).toBeUndefined()
|
||||
expect(after.context).toEqual(
|
||||
attaches ? [`Contents of ${path}:\n\n${content}`] : undefined,
|
||||
)
|
||||
expect(repeated.context).toBeUndefined()
|
||||
|
||||
await started.clock.settle()
|
||||
})
|
||||
}
|
||||
|
||||
test(
|
||||
'the start sends the mode row alone: no walk, no toast',
|
||||
{ plugins: [Fixtures.RECORDING] },
|
||||
|
||||
Reference in New Issue
Block a user