fix(tool-fs): CRLF-safe write diff, opaque meta, doc sync

Address the applied-hunk-diffs review:

- CRLF write overwrite emitted bogus every-line-changed hunks: write's
  `before` was LF-normalized but `after` kept the raw model content, so a
  CRLF rewrite of an LF file diffed every line. Normalize write's `after`
  to LF so both sides share the diff basis (edit already did). Regression
  test proves it fails on the raw-after path.
- The tool-private `meta` payload is now typed `unknown` (opaque) at every
  seam instead of `JsonValue`. This drops the `dsh-tools -> dsh-session`
  package edge that existed only to name the type, and removes the
  `FileDiff` index signature that had been widening the type solely for
  JsonValue-assignability. Serializability is still enforced at runtime by
  `Session.append`'s isJsonValue check, which was always the real guard.
- Sync the docs the new result/meta surface left stale: ToolResultView's
  diff card + ToolExecutionResult.meta in tools.md/session.md type-equiv
  blocks, the acp/tools READMEs, and the adding-a-tool cookbook; regenerate
  the cordis catalog and module graph.
This commit is contained in:
Tianyi Cui
2026-07-03 18:00:16 +08:00
parent d8fd3225af
commit dee2dee402
18 changed files with 63 additions and 68 deletions

View File

@@ -429,4 +429,4 @@ export function applyLiteralEdit(
return { content: content.split(oldNorm).join(newNorm), replacements }
}
export { restoreLineEndings }
export { normalizeLineEndings, restoreLineEndings }

View File

@@ -26,6 +26,7 @@ import type {
} from '@deepseek-ai/dsh-fs'
import {
applyLiteralEdit,
normalizeLineEndings,
probe,
readForEdit,
readTextForDiff,
@@ -156,7 +157,10 @@ export class LocalFileSystem extends FileSystem {
operation: existing ? 'update' : 'create',
version: this.versionAfterWrite(after, target),
before,
after: content,
// LF-normalized to share the diff basis with `before` (also LF): a CRLF
// overwrite must not read as every line changed. Line-ending restoration
// is a storage detail the applied-hunk diff ignores.
after: normalizeLineEndings(content),
}
})
}