From 6c88b380ea8a4a65862000f782bd8ce00b77e184 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:30:04 +0800 Subject: [PATCH] docs(tool-catalog): register dsh-tool-fs in the boot manifest Master's new tool-schema catalog boots every tool-* package and hard-errors if one is absent from the manifest. Add the dsh-tool-fs entry (boot dsh-fs-local to satisfy the injected `fs`, harvest read/write/edit), note that dsh-fs-policy adds the read-before-write/edit gate without changing schemas, and regenerate docs/tool-catalog/tools.md. Update the collectToolCatalog test's expected tool set to include the fs tools. --- docs/tool-catalog/tools.md | 94 +++++++++++++++++++ .../core/tools/tests/gen-tool-catalog.spec.ts | 2 +- scripts/gen-tool-catalog.ts | 16 ++++ 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/docs/tool-catalog/tools.md b/docs/tool-catalog/tools.md index 97400f8223..9f00a66d75 100644 --- a/docs/tool-catalog/tools.md +++ b/docs/tool-catalog/tools.md @@ -91,6 +91,100 @@ Read new output from a background bash task started with `bash` + `run_in_backgr Source: [`packages/bash/tool-bash/src/index.ts`](../../packages/bash/tool-bash/src/index.ts) +## `@deepseek-ai/dsh-tool-fs` + +### `edit` + +Edit an existing UTF-8 text file by replacing literal text. + +```json +{ + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to edit, resolved by the filesystem backend." + }, + "old_string": { + "type": "string", + "description": "Literal text to replace. Must match exactly." + }, + "new_string": { + "type": "string", + "description": "Literal replacement text. Use an empty string to delete the match." + }, + "replace_all": { + "type": "boolean", + "description": "Replace all matches. Defaults to false; when false, old_string must appear exactly once." + } + }, + "required": [ + "file_path", + "old_string", + "new_string" + ] +} +``` + +Source: [`packages/fs/tool-fs/src/index.ts`](../../packages/fs/tool-fs/src/index.ts) + +### `read` + +Read a UTF-8 text file and return line-numbered content. + +```json +{ + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to read, resolved by the filesystem backend." + }, + "offset": { + "type": "number", + "description": "1-based first line to return. Defaults to 1." + }, + "limit": { + "type": "number", + "description": "Maximum number of lines to return. Defaults to 2000." + } + }, + "required": [ + "file_path" + ] +} +``` + +Source: [`packages/fs/tool-fs/src/index.ts`](../../packages/fs/tool-fs/src/index.ts) + +### `write` + +Create or fully replace a UTF-8 text file. + +```json +{ + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to write, resolved by the filesystem backend." + }, + "content": { + "type": "string", + "description": "Full UTF-8 text content to write." + } + }, + "required": [ + "file_path", + "content" + ] +} +``` + +Source: [`packages/fs/tool-fs/src/index.ts`](../../packages/fs/tool-fs/src/index.ts) + +The read-before-write/edit policy is added by `@deepseek-ai/dsh-fs-policy` (an `fs/*` event-gate plugin, no schema change); a deployment that loads these tools is expected to also load it. The tool schemas above are identical with or without the policy plugin. + ## `@deepseek-ai/dsh-tool-subagent` ### `subagent` diff --git a/packages/core/tools/tests/gen-tool-catalog.spec.ts b/packages/core/tools/tests/gen-tool-catalog.spec.ts index eba74c833d..591e57b721 100644 --- a/packages/core/tools/tests/gen-tool-catalog.spec.ts +++ b/packages/core/tools/tests/gen-tool-catalog.spec.ts @@ -35,7 +35,7 @@ describe('gen-tool-catalog collectToolCatalog', () => { it('boots every shipped tool package and harvests its model-facing schemas', async () => { const catalog = await collectToolCatalog() const names = catalog.flatMap(entry => entry.schemas.map(s => s.name)).sort() - expect(names).toEqual(['bash', 'bash_kill', 'bash_output', 'subagent', 'todo_write']) + expect(names).toEqual(['bash', 'bash_kill', 'bash_output', 'edit', 'read', 'subagent', 'todo_write', 'write']) // Every tool carries a JSON-Schema `parameters` object (what the model sees). for (const entry of catalog) { for (const schema of entry.schemas) { diff --git a/scripts/gen-tool-catalog.ts b/scripts/gen-tool-catalog.ts index be318f753c..0efc4354b7 100644 --- a/scripts/gen-tool-catalog.ts +++ b/scripts/gen-tool-catalog.ts @@ -40,9 +40,11 @@ import type { ToolSchema } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' import LocalBashExecutor from '@deepseek-ai/dsh-bash-local' +import LocalFileSystem from '@deepseek-ai/dsh-fs-local' import SubagentService from '@deepseek-ai/dsh-subagent' import * as SubagentMock from '@deepseek-ai/dsh-subagent-mock' import * as ToolBash from '@deepseek-ai/dsh-tool-bash' +import * as ToolFs from '@deepseek-ai/dsh-tool-fs' import * as ToolTodo from '@deepseek-ai/dsh-tool-todo' import * as ToolSubagent from '@deepseek-ai/dsh-tool-subagent' @@ -97,6 +99,20 @@ const TOOL_PACKAGES: ToolPackage[] = [ await ctx.plugin(ToolBash) }, }, + { + pkg: '@deepseek-ai/dsh-tool-fs', + dir: 'tool-fs', + source: 'packages/fs/tool-fs/src/index.ts', + async mount(ctx) { + // The tool injects `fs`; boot the local backend to satisfy it. The schemas + // do not depend on the policy plugin (an event gate that changes behavior, + // not tool shape), so the bare provider is enough to harvest them. + await ctx.plugin(LocalFileSystem) + await ctx.plugin(ToolFs) + }, + note: + 'The read-before-write/edit policy is added by `@deepseek-ai/dsh-fs-policy` (an `fs/*` event-gate plugin, no schema change); a deployment that loads these tools is expected to also load it. The tool schemas above are identical with or without the policy plugin.', + }, { pkg: '@deepseek-ai/dsh-tool-subagent', dir: 'tool-subagent',