mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Merge pull request #859 from deepseek-harness/worktree/fix-snapshot-cwd-boundaries
fix(snapshot): preserve cwd normalization boundaries
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user