Merge pull request #859 from deepseek-harness/worktree/fix-snapshot-cwd-boundaries

fix(snapshot): preserve cwd normalization boundaries
This commit is contained in:
Tianyi Cui
2026-07-29 00:35:26 +08:00
committed by GitHub
2 changed files with 43 additions and 2 deletions

View File

@@ -22,6 +22,7 @@ const EVENT_READ_OMITTED_BYTES_RE = /(\r?\n\r?\n\(Omitted )\d+( bytes\.)/g
const EVENT_READ_TARGET_REGION_RE
= /^Session [^\r\n]+ — [^\r\n]+\r?\nTarget event seq \d+:\r?\n```json\r?\n\{\r?\n[\s\S]*?(?=\r?\n```(?:\r?\n|$)|\r?\n\r?\n\(Omitted )/
const PATH_TEXT_BOUNDARY_RE = /[\s<>'"`()\[\]{},;:!?=]/
const FILE_URI_PATH_PREFIX_RE = /(?:^|[^a-z0-9+.-])file:\/\/\/?$/i
/** A UUID v4 string, the shape `randomUUID()` produces for session ids. */
const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi
@@ -97,12 +98,14 @@ function isCwdMatch(value: string, start: number, length: number): boolean {
const before = value[start - 1]
const after = value[start + length]
const afterPunctuation = value[start + length + 1]
const startsAtBoundary = before === undefined || PATH_TEXT_BOUNDARY_RE.test(before)
const startsAtBoundary = before === undefined
|| PATH_TEXT_BOUNDARY_RE.test(before)
|| FILE_URI_PATH_PREFIX_RE.test(value.slice(0, start))
const endsAtBoundary = after === undefined
|| after === '/'
|| after === '\\'
|| PATH_TEXT_BOUNDARY_RE.test(after)
|| after === '.' && (afterPunctuation === undefined || /\s/.test(afterPunctuation))
|| after === '.' && (afterPunctuation === undefined || PATH_TEXT_BOUNDARY_RE.test(afterPunctuation))
return startsAtBoundary && endsAtBoundary
}

View File

@@ -46,6 +46,28 @@ describe('normalizeStdout', () => {
expect(out).not.toContain(ctx.sessionIds[0] as string)
})
it('scrubs cwd at file URI and chained-punctuation boundaries', () => {
const raw = JSON.stringify({
jsonrpc: '2.0',
method: 'session/update',
params: {
uri: `file://${ctx.cwd}/proof.txt`,
punctuated: `${ctx.cwd}.,`,
dottedSegment: `${ctx.cwd}.backup`,
dashedSegment: `${ctx.cwd}-backup`,
},
})
const frame = JSON.parse(normalizeStdout(raw, ctx)) as {
params: Record<string, string>
}
expect(frame.params).toEqual({
uri: 'file://{{cwd}}/proof.txt',
punctuated: '{{cwd}}.,',
dottedSegment: `${ctx.cwd}.backup`,
dashedSegment: `${ctx.cwd}-backup`,
})
})
it('scrubs every filesystem spelling of the cwd longest-first', () => {
const longCwd = String.raw`C:\Users\runneradmin\AppData\Local\Temp\acp-snapshot`
const aliasedCtx: NormalizeContext = {
@@ -213,6 +235,22 @@ describe('normalizeSessionLog', () => {
expect(out).not.toContain(ctx.cwd)
})
it('scrubs cwd at file URI and chained-punctuation boundaries in event data', () => {
const ev = JSON.stringify({
type: 'tool/result',
seq: 2,
time: 5,
data: {
uri: `file://${ctx.cwd}/proof.txt`,
punctuated: `${ctx.cwd}.,`,
},
})
const out = normalizeSessionLog(`${header({ cwd: ctx.cwd })}\n${ev}\n`, ctx)
expect(out).toContain('file://{{cwd}}/proof.txt')
expect(out).toContain('{{cwd}}.,')
expect(out).not.toContain(`file://${ctx.cwd}`)
})
it('scrubs random local spill paths under the snapshot cwd', () => {
const ev = JSON.stringify({
type: 'tool/result', seq: 2, time: 5,