From f9db1a6a08b4af895f33b8d01957801aa727714e Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 14 Jul 2026 03:30:23 +0800 Subject: [PATCH] refactor: hide filesystem implementation helpers --- docs/config-catalog.md | 4 ++-- packages/fs/fs-local/README.md | 2 +- packages/fs/fs-local/src/index.ts | 14 -------------- packages/fs/fs-local/tests/fsio.spec.ts | 4 ++-- packages/fs/tool-fs/README.md | 2 +- packages/fs/tool-fs/src/index.ts | 9 --------- packages/fs/tool-fs/tests/diff.spec.ts | 2 +- packages/fs/tool-fs/tests/read-render.spec.ts | 4 ++-- packages/fs/tool-fs/tests/tools.spec.ts | 5 +++-- 9 files changed, 12 insertions(+), 34 deletions(-) diff --git a/docs/config-catalog.md b/docs/config-catalog.md index 9d4b8038b5..a5eb611f02 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -265,7 +265,7 @@ export interface Config { } ``` -Source: [`packages/fs/fs-local/src/index.ts:58`](../packages/fs/fs-local/src/index.ts) +Source: [`packages/fs/fs-local/src/index.ts:44`](../packages/fs/fs-local/src/index.ts) ## `@deepseek-ai/dsh-hooks-claude` @@ -851,7 +851,7 @@ export interface Config { } ``` -Source: [`packages/fs/tool-fs/src/index.ts:48`](../packages/fs/tool-fs/src/index.ts) +Source: [`packages/fs/tool-fs/src/index.ts:39`](../packages/fs/tool-fs/src/index.ts) ## `@deepseek-ai/dsh-tool-skill` diff --git a/packages/fs/fs-local/README.md b/packages/fs/fs-local/README.md index 26524fad24..a2ea5de742 100644 --- a/packages/fs/fs-local/README.md +++ b/packages/fs/fs-local/README.md @@ -23,4 +23,4 @@ await ctx.plugin(LocalFileSystem, { cwd: process.cwd() }) `config.cwd` is a resolution default, not a containment boundary — absolute paths and `..` escape it. Enforce containment with a stricter `ctx.fs` backend or a permission plugin on the `tools/execute` waterfall. See [the filesystem capability-seam RFC's Consequences section](../../../docs/rfc/implemented/architecture/2026-06-17-filesystem-capability-seam.md#consequences). -The raw I/O lives in `src/fsio.ts` (Cordis-free, independently unit-tested); `src/index.ts` is the thin service wiring. +The package-root SDK surface is the default/named `LocalFileSystem` class plus `Config`. Raw I/O lives in `src/fsio.ts` (Cordis-free, independently unit-tested); `src/index.ts` is the thin service wiring. diff --git a/packages/fs/fs-local/src/index.ts b/packages/fs/fs-local/src/index.ts index 1a3ebc57f6..8a9294a4a6 100644 --- a/packages/fs/fs-local/src/index.ts +++ b/packages/fs/fs-local/src/index.ts @@ -40,20 +40,6 @@ import { } from './fsio.ts' import type { FsIoInternals } from './fsio.ts' -export { - applyLiteralEdit, - listDirectory, - probe, - readForEdit, - readTextForDiff, - readWholeText, - resolveLocalTarget, - restoreLineEndings, - streamWholeText, - writeFileAtomic, -} from './fsio.ts' -export type { FsIoInternals, LineEndings, LocalDirEntry, LocalTarget, PathInfo } from './fsio.ts' - /** Configuration for the local filesystem backend. */ export interface Config { /** Base directory for relative paths. Defaults to `process.cwd()`. */ diff --git a/packages/fs/fs-local/tests/fsio.spec.ts b/packages/fs/fs-local/tests/fsio.spec.ts index 3a30f73ed2..6723ae9d9c 100644 --- a/packages/fs/fs-local/tests/fsio.spec.ts +++ b/packages/fs/fs-local/tests/fsio.spec.ts @@ -20,8 +20,8 @@ import { restoreLineEndings, streamWholeText, writeFileAtomic, -} from '@deepseek-ai/dsh-fs-local' -import type { LocalTarget } from '@deepseek-ai/dsh-fs-local' +} from '../src/fsio.ts' +import type { LocalTarget } from '../src/fsio.ts' import { FsError, FsTargetKey } from '@deepseek-ai/dsh-fs' let dir: string diff --git a/packages/fs/tool-fs/README.md b/packages/fs/tool-fs/README.md index fedd1ff7a2..a72bfaf201 100644 --- a/packages/fs/tool-fs/README.md +++ b/packages/fs/tool-fs/README.md @@ -46,4 +46,4 @@ The tool passes `exec` (the tool-execution context) as the opaque `actor` on eve `fs/observed` fires AFTER the read/write/edit already succeeded, via a plain `ctx.emit`. A listener is contractually a synchronous, side-effect-only recorder (`@deepseek-ai/dsh-fs-policy`'s is a `WeakMap.set`); the tool does not guard the emit, so a listener that throws would surface as the tool's `isError` result — async or fallible observation does not belong on this event. -The read rendering (line windowing + output formatting) lives in `src/read-render.ts` (Cordis-free, independently unit-tested); `src/read.ts`/`write.ts`/`edit.ts` are the tool executors and `src/index.ts` composes them. +The package root exports only the Cordis plugin contract (`name`, `inject`, `Config`, and `apply`). Read rendering (line windowing + output formatting) lives in `src/read-render.ts` (Cordis-free, independently unit-tested); `src/read.ts`/`write.ts`/`edit.ts` are the tool executors and `src/index.ts` composes them. diff --git a/packages/fs/tool-fs/src/index.ts b/packages/fs/tool-fs/src/index.ts index f5d0d9ef91..83e19bb18a 100644 --- a/packages/fs/tool-fs/src/index.ts +++ b/packages/fs/tool-fs/src/index.ts @@ -29,15 +29,6 @@ import { applyWriteTool } from './write.ts' import { applyEditTool } from './edit.ts' import { READ_MAX_BYTES, READ_MAX_LINE_LENGTH } from './read-render.ts' -export { READ_LIMIT, STREAM_MIN_SIZE, applyReadTool, parseReadArgs } from './read.ts' -export type { ReadToolCaps } from './read.ts' -export { applyWriteTool, formatWriteOutput, parseWriteArgs } from './write.ts' -export { applyEditTool, formatEditOutput, parseEditArgs } from './edit.ts' -export { READ_MAX_BYTES, READ_MAX_LINE_LENGTH, buildWindow, formatReadOutput } from './read-render.ts' -export type { FileReadOutcome, FileTextLine, ReadWindow, WindowResult } from './read-render.ts' -export { DIFF_CONTEXT, computeHunkDiffs, diffsFromMeta } from './diff.ts' -export type { FsDiffMeta } from './diff.ts' - /** Cordis plugin name used by loader diagnostics. */ export const name = 'tool-fs' diff --git a/packages/fs/tool-fs/tests/diff.spec.ts b/packages/fs/tool-fs/tests/diff.spec.ts index 12ab7209b6..21f977f0fa 100644 --- a/packages/fs/tool-fs/tests/diff.spec.ts +++ b/packages/fs/tool-fs/tests/diff.spec.ts @@ -6,7 +6,7 @@ */ import { describe, expect, it } from 'vitest' -import { computeHunkDiffs, diffsFromMeta, DIFF_CONTEXT } from '@deepseek-ai/dsh-tool-fs' +import { computeHunkDiffs, diffsFromMeta, DIFF_CONTEXT } from '../src/diff.ts' import type { JsonValue } from '@deepseek-ai/dsh-session' const lines = (n: number): string => Array.from({ length: n }, (_, i) => `line${i + 1}`).join('\n') + '\n' diff --git a/packages/fs/tool-fs/tests/read-render.spec.ts b/packages/fs/tool-fs/tests/read-render.spec.ts index c23ad79170..ab4d2a618b 100644 --- a/packages/fs/tool-fs/tests/read-render.spec.ts +++ b/packages/fs/tool-fs/tests/read-render.spec.ts @@ -6,8 +6,8 @@ */ import { describe, expect, it } from 'vitest' -import { buildWindow, READ_MAX_BYTES, READ_MAX_LINE_LENGTH } from '@deepseek-ai/dsh-tool-fs' -import type { ReadWindow } from '@deepseek-ai/dsh-tool-fs' +import { buildWindow, READ_MAX_BYTES, READ_MAX_LINE_LENGTH } from '../src/read-render.ts' +import type { ReadWindow } from '../src/read-render.ts' const DEFAULT_CAPS = { maxLineLength: READ_MAX_LINE_LENGTH, maxBytes: READ_MAX_BYTES } const READ_ALL: ReadWindow = { offset: 1, limit: 2000, ...DEFAULT_CAPS } diff --git a/packages/fs/tool-fs/tests/tools.spec.ts b/packages/fs/tool-fs/tests/tools.spec.ts index c17bd875ba..c7e1a64cbe 100644 --- a/packages/fs/tool-fs/tests/tools.spec.ts +++ b/packages/fs/tool-fs/tests/tools.spec.ts @@ -25,8 +25,9 @@ import type { } from '@deepseek-ai/dsh-fs' import * as FsPolicy from '@deepseek-ai/dsh-fs-policy' import * as ToolFs from '@deepseek-ai/dsh-tool-fs' -import { formatReadOutput, STREAM_MIN_SIZE } from '@deepseek-ai/dsh-tool-fs' -import type { FileReadOutcome } from '@deepseek-ai/dsh-tool-fs' +import { STREAM_MIN_SIZE } from '../src/read.ts' +import { formatReadOutput } from '../src/read-render.ts' +import type { FileReadOutcome } from '../src/read-render.ts' /** An in-memory fake provider; a test can arm a rejection on any primitive. */ class FakeFs extends FileSystem {