@deepseek-ai/dsh-tool-fs-search 0.0.1-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.i18n.yaml +6 -0
- package/README.md +134 -0
- package/README.zh.md +134 -0
- package/lib/index.js +1264 -0
- package/lib/invariant.js +23 -0
- package/lib/types/glob.d.ts +146 -0
- package/lib/types/grep.d.ts +141 -0
- package/lib/types/index.d.ts +71 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/presentation.d.ts +125 -0
- package/lib/types/search-core.d.ts +208 -0
- package/lib/types/surface.d.ts +15 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, DeepSeek
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/fs/tool-fs-search/README.md
|
|
5
|
+
README.md: 7803ce52c1b9d2d858dadb718edd163585360aef
|
|
6
|
+
README.zh.md: 3a34f4e8a04666b72f09eca1b41fea825d5a609f
|
package/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-tool-fs-search
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
The **model-facing filesystem discovery tools**—`glob`, `grep`—are backed by the **packaged ripgrep binary** (`@vscode/ripgrep`), not by `ctx.fs` provider methods and not by a system `rg` install. Registration is unconditional: the binary ships inside the npm dependency, so there is no load-time availability probe. Each call spawns the binary through the `ctx.subprocess` seam with a fixed argv vector (`--no-config` prepended so a host `RIPGREP_CONFIG_PATH` cannot inject a `--pre` preprocessor into the unconfined spawn; model-controlled values are plain argv elements — no shell layer exists, so no quoting applies), parses the raw `rg` output, and returns a workdir-relative canonical value. The package injects `tools`, `systemPrompt`, and `subprocess`—deliberately **not** `fs`; `ctx.spillStore` is read opportunistically with `ctx.get()` because formatted-result spill is optional.
|
|
6
|
+
|
|
7
|
+
```ts ignore-check
|
|
8
|
+
// A deployment chooses how over-cap glob pages are selected.
|
|
9
|
+
await ctx.plugin(LocalSubprocessService) // @deepseek-ai/dsh-subprocess-local
|
|
10
|
+
await ctx.plugin(ToolFsSearch, { sampleOverCapGlobResults: false })
|
|
11
|
+
// Optional: a spill backend makes capped results fully recoverable.
|
|
12
|
+
await ctx.plugin(LocalSpillStore) // @deepseek-ai/dsh-spill-local
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Why spawn-backed: local workspace discovery is naturally a process-backed `rg` workflow, and putting search on `ctx.fs` would force every filesystem backend to grow a search API. The subprocess seam owns spawn execution, process-tree termination, environment scrubbing, and bounded output capture; this package owns schemas, argument validation, argv construction, parsing, retention, formatted-result spill, and timeout declaration. The tools never expose a background task — the call returns only after `rg` exits, is terminated by the cooperative timeout, is aborted, or fails.
|
|
16
|
+
|
|
17
|
+
## Deployment requirement: no host rg, co-located workdir/filesystem
|
|
18
|
+
|
|
19
|
+
The binary ships with the package on every supported platform (macOS/Linux/Windows, x64/arm64), so no host `rg` install is required and the tools register on every deployment. Returned paths are displayed relative to the resolved workdir (the calling agent's session cwd when present, else `process.cwd()`) and are follow-up-readable with `read` only when that workdir and the filesystem root are the same workspace. That co-location requirement carries no runtime cross-service validation; remote or virtual filesystem search waits for a shared workspace contract or a provider-specific search backend.
|
|
20
|
+
|
|
21
|
+
## Config
|
|
22
|
+
|
|
23
|
+
`sampleOverCapGlobResults` is required and has no fallback; deployments choose the over-cap ordering contract explicitly. The remaining keys are optional search caps with the defaults below.
|
|
24
|
+
|
|
25
|
+
| Key | Default | Meaning |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `sampleOverCapGlobResults` | none (required) | `true` samples an over-cap `glob` page across top-level entries; `false` keeps the modification-time-ordered head. When formatted spill succeeds, both modes preserve the complete sorted list in that artifact. |
|
|
28
|
+
| `globMaxResults` | `100` | Max paths one `glob` call shows inline (matches Claude Code's `GlobTool` limit). A result within the cap remains complete and modification-time ordered. |
|
|
29
|
+
| `grepMaxMatches` | `250` | Max flat matches one `grep` call retains inline (matches Claude Code's `GrepTool` `head_limit`); later matches go to the formatted spill artifact. |
|
|
30
|
+
| `grepMaxLineBytes` | `2000` | Byte cap per matched-line preview; the cut preserves UTF-8 boundaries and is marked `(line truncated)`. |
|
|
31
|
+
| `rawOutputMaxBytes` | `20000000` | Max complete raw `rg` stdout a search will parse (matches Claude Code's ripgrep raw buffer); larger raw output fails with `SEARCH_RAW_OUTPUT_OVERFLOW`. |
|
|
32
|
+
| `timeoutMs` | `30000` | Cooperative tool-call budget attached to both tool definitions, enforced by `@deepseek-ai/dsh-timeout-policy` through `exec.signal`; the subprocess seam's terminate escalation is the hard kill. |
|
|
33
|
+
| `graceMs` | `3000` | Positive terminate-escalation grace the subprocess seam grants past `timeoutMs` before the search fails as `SEARCH_ABORTED`; it cannot exceed [`MAX_TIMER_DELAY_MS`](../../util/timeout/README.md). |
|
|
34
|
+
| `stderrMaxBytes` | `65536` | Diagnostic-tail budget for `rg` stderr, captured through the subprocess seam's collect disposition; a lossy read keeps only the tail (marked `[stderr truncated]`). |
|
|
35
|
+
|
|
36
|
+
## Tools
|
|
37
|
+
|
|
38
|
+
| Tool | Arguments | Behavior |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `glob` | `pattern`, `path?` | `rg --files --glob <pattern> --sort=modified --no-ignore --hidden` plus VCS metadata excludes (`.git`, `.svn`, `.hg`, `.bzr`, `.jj`, `.sl`). `path` is an optional **directory** search root; omitted means the resolved workdir. Returns one FILE path per line; `rg --files` never emits directory entries. The pattern keeps ripgrep semantics: without a `/` it matches the basename at any depth, so `*` matches the whole tree. Complete results stay modification-time ordered; over-cap presentation follows `sampleOverCapGlobResults`. |
|
|
41
|
+
| `grep` | `pattern`, `path?`, `include?` | Line-oriented `rg --json` parse (no colon-splitting ambiguity). `pattern` is a ripgrep regex; `path` is an optional **file or directory** target; `include` is ONE positive glob filter — a comma-separated list or a negated (`!…`) value is rejected up front (brace alternation like `*.{ts,tsx}` is fine). Returns matches grouped by file as `Line N: <preview>`. |
|
|
42
|
+
|
|
43
|
+
Routine budgets stay out of the model-facing schema (no `head_limit`/`offset`/`case_insensitive`/output modes): a model that needs surrounding context reads the matched file with `read`; one that needs later results follows the returned spill locator's retrieval hint.
|
|
44
|
+
|
|
45
|
+
## Two budgets, two artifacts
|
|
46
|
+
|
|
47
|
+
Raw `rg` stdout and stderr are internal transport details. Each search requests collect-mode budgets from the subprocess seam — complete stdout within `rawOutputMaxBytes` and a `stderrMaxBytes` diagnostic tail — with no spill files on either stream (the tool never reads a raw spill path). If the seam still reports a lossy stdout read, the search fails with `SEARCH_RAW_OUTPUT_OVERFLOW` and tells the model to narrow the query; a lossy stderr read only marks the diagnostic excerpt `[stderr truncated]`. A successful `glob` keeps the displayed search root and every acquired path in `{ root, paths }`; when sampling is enabled, `root` lets the Native renderer group an explicit relative or absolute search path by entries beneath that root rather than by its workdir prefix. `grep` keeps every acquired `{ path, lineNumber, line }` in `{ matches }`. Inline item and per-line preview caps apply only in the Native renderer. For a direct surface call with more logical results than the inline cap, post-policy best-effort saves the complete formatted preview through `ctx.spillStore.saveText()` and replaces only presentation with the configured page plus locator. Nested Code dispatches skip that spill because their full canonical value does not enter model context. Missing/failed spill keeps the inline page and reports that the complete result could not be saved—never an `isError`.
|
|
48
|
+
|
|
49
|
+
## Errors
|
|
50
|
+
|
|
51
|
+
Search failures carry the package-owned `SearchError` (a `HarnessError` subclass), surfaced as `{ name, code }` on `isError` results: `SEARCH_INVALID_PATTERN` (ripgrep rejected the regex/glob), `SEARCH_FAILED` (a failed `rg` launch, inaccessible target, signal kill, malformed `--json` output), `SEARCH_RAW_OUTPUT_OVERFLOW` (raw output over `rawOutputMaxBytes`, or still lossy after the requested stdout capture budget), and `SEARCH_ABORTED` (cooperative tool timeout or caller cancellation). ripgrep exit semantics are tool-owned: exit 0 is success with results, exit 1 is a successful empty search (`No files found` / `No matches found`), and only other exits are failures. Model argument mistakes (blank pattern, a list-valued `include`) stay ordinary tool argument errors.
|
|
52
|
+
|
|
53
|
+
## Model Experience
|
|
54
|
+
|
|
55
|
+
### System prompt
|
|
56
|
+
|
|
57
|
+
#### What the model sees
|
|
58
|
+
|
|
59
|
+
Every request in this plugin's registration scope contains the independently registered glob and grep guidance below. Agent-scoped tool restrictions can hide either schema without removing its prompt section.
|
|
60
|
+
|
|
61
|
+
##### Glob guidance with `sampleOverCapGlobResults: true`
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
Use the glob tool — not shell find — to discover files by path pattern. A pattern with no "/" matches basenames at any depth, so "*" matches every file in the tree rather than its top level. Results are files only, never directories, and include hidden and ignored files: a result that fits comes back in modification-time order, while a larger one is sampled across top-level entries, so it spans the tree instead of one subtree.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
##### Glob guidance with `sampleOverCapGlobResults: false`
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
Use the glob tool — not shell find — to discover files by path pattern. A pattern with no "/" matches basenames at any depth, so "*" matches every file in the tree rather than its top level. Results are files only, never directories, and include hidden and ignored files: a result that fits comes back in modification-time order, while a larger one keeps the modification-time-ordered head.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
##### Grep guidance
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
Use the grep tool — not shell grep or rg — to search file contents. Use read on a matched file when you need surrounding context.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Token effect
|
|
80
|
+
|
|
81
|
+
Fixed guidance cost per request while the tools are registered; the required sampling choice selects one glob variant.
|
|
82
|
+
|
|
83
|
+
#### KV Cache effect
|
|
84
|
+
|
|
85
|
+
Prefix-stable while the plugin scope, sampling choice, and guidance text are unchanged. Activation, disposal, or changing the choice may invalidate reuse from this prompt section.
|
|
86
|
+
|
|
87
|
+
### Tool schemas
|
|
88
|
+
|
|
89
|
+
#### What the model sees
|
|
90
|
+
|
|
91
|
+
The glob description states the configured over-cap ordering. The generated [`glob` and `grep` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-fs-search) use `sampleOverCapGlobResults: true`; the tools are registered unconditionally.
|
|
92
|
+
|
|
93
|
+
#### Token effect
|
|
94
|
+
|
|
95
|
+
Fixed schema cost on every request where the tools are visible.
|
|
96
|
+
|
|
97
|
+
#### KV Cache effect
|
|
98
|
+
|
|
99
|
+
Prefix-stable while tool visibility and definitions are unchanged. Registration lifecycle or scoped restrictions may invalidate reuse from the first changed schema token.
|
|
100
|
+
|
|
101
|
+
### Results and spill notices
|
|
102
|
+
|
|
103
|
+
#### What the model sees
|
|
104
|
+
|
|
105
|
+
`glob` returns one path per line; `grep` groups `Line <line>: <preview>` matches beneath each path. Empty searches return `No files found` or `No matches found`. A capped result ends with its omission count plus the spill locator and backend retrieval hint, or says the complete result could not be saved. With `sampleOverCapGlobResults: true`, an over-cap `glob` page takes paths round-robin across entries immediately beneath the actual search root, and the footer states the sampled basis and how many top-level entries it reached; when it cannot reach them all, the footer tells the model to narrow `path`. With `false`, the page is the modification-time-ordered head and keeps the plain capped-result footer. A result that fits inline is untouched, and a flat sampled result also keeps the plain footer because its sample equals the modification-time head. The spill artifact always holds the complete list in modification-time order.
|
|
106
|
+
|
|
107
|
+
#### Token effect
|
|
108
|
+
|
|
109
|
+
Inline paths and matches are bounded by `globMaxResults`, `grepMaxMatches`, and `grepMaxLineBytes`; the call and retained result remain in history until compaction.
|
|
110
|
+
|
|
111
|
+
#### KV Cache effect
|
|
112
|
+
|
|
113
|
+
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
|
114
|
+
|
|
115
|
+
### Tool errors
|
|
116
|
+
|
|
117
|
+
#### What the model sees
|
|
118
|
+
|
|
119
|
+
Failures are normalized as `Error: <message>` with structured `SEARCH_INVALID_PATTERN`, `SEARCH_FAILED`, `SEARCH_RAW_OUTPUT_OVERFLOW`, or `SEARCH_ABORTED` metadata for callers.
|
|
120
|
+
|
|
121
|
+
#### Token effect
|
|
122
|
+
|
|
123
|
+
Only a failing call adds these retained tokens.
|
|
124
|
+
|
|
125
|
+
#### KV Cache effect
|
|
126
|
+
|
|
127
|
+
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
|
128
|
+
|
|
129
|
+
## Known Limitations and Deferred Work
|
|
130
|
+
|
|
131
|
+
- **Search and file access have no shared-workspace proof** — returned paths are follow-up-readable only when the workdir and filesystem root denote the same workspace; the package performs no runtime cross-service validation.
|
|
132
|
+
- **The packaged binary is fixed at dependency version** — `@vscode/ripgrep` covers the platforms it ships (macOS/Linux/Windows, x64/arm64); an unsupported platform or a corrupted install fails calls with `SEARCH_FAILED`. Remote or virtual filesystems need a co-located workspace or another search consumer.
|
|
133
|
+
- **The schemas expose one bounded page** — offset pagination, case-mode switches, alternate output modes, and provider-backed discovery remain outside this package; capped complete output requires a spill backend.
|
|
134
|
+
- **Sampling, when enabled, groups by first path segment beneath the search root only** — an over-cap `glob` page balances across those top-level entries, so a result concentrated deeper (one busy directory inside an otherwise even tree) is still shown unevenly below that level; recursive balancing is deferred.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-tool-fs-search
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
**面向模型的文件系统发现工具**(`glob`、`grep`)由 **打包的 ripgrep 二进制**(`@vscode/ripgrep`)支持,而不是由 `ctx.fs` 提供方方法或系统 `rg` 安装支持。注册是无条件的:二进制随 NPM 依赖一起交付,因此没有加载期可用性探针。每次调用都通过 `ctx.subprocess` seam 以固定 argv 向量 spawn 该二进制(前缀 `--no-config`,使宿主的 `RIPGREP_CONFIG_PATH` 无法向不受约束的 spawn 注入 `--pre` 预处理器;模型控制的值是普通 argv 元素——不存在 shell 层,因此不涉及 shell 引号处理),解析原始 `rg` 输出,并返回相对于工作目录的规范值。本包注入 `tools`、`systemPrompt` 和 `subprocess`,有意**不**注入 `fs`;格式化结果 spill 为可选功能,因此机会性读取 `ctx.spillStore`,调用方式为 `ctx.get()`。
|
|
6
|
+
|
|
7
|
+
```ts ignore-check
|
|
8
|
+
// A deployment chooses how over-cap glob pages are selected.
|
|
9
|
+
await ctx.plugin(LocalSubprocessService) // @deepseek-ai/dsh-subprocess-local
|
|
10
|
+
await ctx.plugin(ToolFsSearch, { sampleOverCapGlobResults: false })
|
|
11
|
+
// Optional: a spill backend makes capped results fully recoverable.
|
|
12
|
+
await ctx.plugin(LocalSpillStore) // @deepseek-ai/dsh-spill-local
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
采用 spawn 支持的原因:本地工作区发现天然是由进程支持的 `rg` 工作流;如果把搜索放到 `ctx.fs` 上,就会迫使每个文件系统后端扩展搜索 API。subprocess seam 负责 spawn 执行、进程树终止、环境清理和有界输出捕获;本包负责 schema、参数校验、argv 构造、解析、保留、格式化结果 spill 和超时声明。工具绝不暴露后台任务——只有在 `rg` 退出、被协作式超时终止、被中止或失败后,调用才会返回。
|
|
16
|
+
|
|
17
|
+
## 部署要求:无需宿主 rg,但工作目录与文件系统需共置
|
|
18
|
+
|
|
19
|
+
二进制随包交付,覆盖所有受支持平台(macOS/Linux/Windows,x64/arm64),因此无需宿主 `rg` 安装,工具在每个部署上都注册。返回路径会相对于解析后的工作目录显示(调用方 agent(智能体)有会话 cwd 时使用该 cwd,否则使用 `process.cwd()`);只有该工作目录与文件系统根目录是同一工作区时,才能用 `read` 继续读取。这项共置要求不附带运行时跨服务校验;远程或虚拟文件系统搜索需等待共享工作区约定或特定提供方的搜索后端。
|
|
20
|
+
|
|
21
|
+
## 配置
|
|
22
|
+
|
|
23
|
+
`sampleOverCapGlobResults` 是必填项且没有回退值;部署必须显式选择超过上限时的排序约定。其余配置键是可选的搜索上限,默认值如下。
|
|
24
|
+
|
|
25
|
+
| 配置键 | 默认值 | 含义 |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `sampleOverCapGlobResults` | 无(必填) | `true` 会在顶层条目之间对超过上限的 `glob` 页面采样;`false` 保留按修改时间排序的前部。格式化 spill 成功时,两种模式都会在该产物中保留完整排序列表。 |
|
|
28
|
+
| `globMaxResults` | `100` | 一次 `glob` 调用内联展示的最大路径数(与 Claude Code 的 `GlobTool` 上限相同)。未超过上限的结果保持完整,并按修改时间排序。 |
|
|
29
|
+
| `grepMaxMatches` | `250` | 一次 `grep` 调用内联保留的最大平铺匹配数(与 Claude Code 的 `GrepTool` `head_limit` 相同);后续匹配写入格式化 spill 产物。 |
|
|
30
|
+
| `grepMaxLineBytes` | `2000` | 每条匹配行预览的字节上限;截断会保留 UTF-8 边界,并标记为 `(line truncated)`。 |
|
|
31
|
+
| `rawOutputMaxBytes` | `20000000` | 搜索将解析的完整原始 `rg` stdout 上限(与 Claude Code 的 ripgrep 原始 buffer 相同);更大的原始输出以 `SEARCH_RAW_OUTPUT_OVERFLOW` 失败。 |
|
|
32
|
+
| `timeoutMs` | `30000` | 附加到两个工具定义上的协作式工具调用预算,由 `@deepseek-ai/dsh-timeout-policy` 通过 `exec.signal` 强制执行;subprocess seam 的终止升级提供硬终止。 |
|
|
33
|
+
| `graceMs` | `3000` | subprocess seam 在 `timeoutMs` 之外授予的终止升级宽限期须为正值;超过后搜索以 `SEARCH_ABORTED` 失败;该宽限期不得大于 [`MAX_TIMER_DELAY_MS`](../../util/timeout/README.md)。 |
|
|
34
|
+
| `stderrMaxBytes` | `65536` | `rg` stderr 的诊断尾部预算,经 subprocess seam 的 collect 形态捕获;lossy 读取只保留尾部(标记 `[stderr truncated]`)。 |
|
|
35
|
+
|
|
36
|
+
## 工具
|
|
37
|
+
|
|
38
|
+
| 工具 | 参数 | 行为 |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `glob` | `pattern`、`path?` | 运行 `rg --files --glob <pattern> --sort=modified --no-ignore --hidden`,并排除 VCS 元数据(`.git`、`.svn`、`.hg`、`.bzr`、`.jj`、`.sl`)。`path` 是可选的**目录**搜索根;省略时使用解析后的工作目录。每行返回一个**文件**路径;`rg --files` 从不输出目录条目。pattern 保留 ripgrep 语义:不含 `/` 时匹配任意深度的基名,因此 `*` 匹配整棵树。完整结果保持按修改时间排序;超过上限时的呈现方式遵循 `sampleOverCapGlobResults`。 |
|
|
41
|
+
| `grep` | `pattern`、`path?`、`include?` | 按行解析 `rg --json`,避免按冒号拆分的歧义。`pattern` 是 ripgrep 正则表达式;`path` 是可选的**文件或目录**目标;`include` 是一个正向 glob 过滤器,前置拒绝逗号分隔列表或否定值(`!…`),但允许 `*.{ts,tsx}` 等花括号交替。返回按文件分组、形如 `Line N: <preview>` 的匹配。 |
|
|
42
|
+
|
|
43
|
+
常规预算不进入面向模型的 schema(没有 `head_limit`/`offset`/`case_insensitive`/输出模式):模型需要周边上下文时,用 `read` 读取匹配文件;需要后续结果时,遵循返回的 spill locator 检索提示。
|
|
44
|
+
|
|
45
|
+
## 两类预算、两类产物
|
|
46
|
+
|
|
47
|
+
原始 `rg` stdout 与 stderr 是内部传输细节。每次搜索从 subprocess seam 请求 collect 模式预算——`rawOutputMaxBytes` 内的完整 stdout 与 `stderrMaxBytes` 的诊断尾部——两条流都不产生 spill 文件(工具从不读取原始 spill 路径)。如果 seam 仍报告 lossy stdout 读取,搜索会以 `SEARCH_RAW_OUTPUT_OVERFLOW` 失败,并要求模型缩小查询;lossy stderr 读取只把诊断摘录标记为 `[stderr truncated]`。成功的 `glob` 在 `{ root, paths }` 中保留所显示的搜索根及所有已取得路径;启用采样时,借助 `root`,Native 渲染器能以显式的相对或绝对搜索路径为根,按该根下的条目分组,而不是按其工作目录前缀分组。`grep` 保留所有已取得的 `{ path, lineNumber, line }`,并将其存入 `{ matches }`。内联条目和每行预览上限只应用于 Native 渲染器。直接接口调用的逻辑结果超过内联上限时,后置策略会尽力通过 `ctx.spillStore.saveText()` 保存完整格式化预览,并只把呈现替换为配置指定的页面与 locator。嵌套 Code 分派会跳过 spill,因为其完整规范值不会进入模型上下文。spill 缺失/失败时保留内联页面,并报告完整结果无法保存,绝不会成为 `isError`。
|
|
48
|
+
|
|
49
|
+
## 错误
|
|
50
|
+
|
|
51
|
+
搜索失败会携带由本包定义的 `SearchError`(`HarnessError` 子类),并以 `{ name, code }` 的形式呈现在 `isError` 结果上:`SEARCH_INVALID_PATTERN`(ripgrep 拒绝正则/glob)、`SEARCH_FAILED`(`rg` 启动失败、目标不可访问、信号终止、`--json` 输出格式错误)、`SEARCH_RAW_OUTPUT_OVERFLOW`(原始输出超过 `rawOutputMaxBytes`,或在请求 stdout 捕获预算后仍 lossy)和 `SEARCH_ABORTED`(协作式工具超时或调用方取消)。ripgrep 的退出语义由工具负责处理:退出 0 表示成功且有结果,退出 1 表示成功的空搜索(`No files found` / `No matches found`),只有其他退出值表示失败。模型参数错误(空白 pattern、列表值 `include`)仍是普通工具参数错误。
|
|
52
|
+
|
|
53
|
+
## 模型体验
|
|
54
|
+
|
|
55
|
+
### 系统提示词
|
|
56
|
+
|
|
57
|
+
#### 模型看到的内容
|
|
58
|
+
|
|
59
|
+
该插件注册作用域内的每个请求都包含下方独立注册的 glob 与 grep 指导。agent 作用域的工具限制可以隐藏任一 schema,而不移除其提示词段。
|
|
60
|
+
|
|
61
|
+
##### 启用 `sampleOverCapGlobResults: true` 时的 Glob 指导
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
Use the glob tool — not shell find — to discover files by path pattern. A pattern with no "/" matches basenames at any depth, so "*" matches every file in the tree rather than its top level. Results are files only, never directories, and include hidden and ignored files: a result that fits comes back in modification-time order, while a larger one is sampled across top-level entries, so it spans the tree instead of one subtree.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
##### 启用 `sampleOverCapGlobResults: false` 时的 Glob 指导
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
Use the glob tool — not shell find — to discover files by path pattern. A pattern with no "/" matches basenames at any depth, so "*" matches every file in the tree rather than its top level. Results are files only, never directories, and include hidden and ignored files: a result that fits comes back in modification-time order, while a larger one keeps the modification-time-ordered head.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
##### Grep 指导
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
Use the grep tool — not shell grep or rg — to search file contents. Use read on a matched file when you need surrounding context.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Token 影响
|
|
80
|
+
|
|
81
|
+
工具注册期间每个请求有固定的指导成本;必填的采样选择决定采用哪一个 glob 变体。
|
|
82
|
+
|
|
83
|
+
#### KV Cache 影响
|
|
84
|
+
|
|
85
|
+
插件作用域、采样选择与指导文本不变时前缀稳定。激活、dispose(资源释放)或改变选择可能使该提示词段的复用失效。
|
|
86
|
+
|
|
87
|
+
### 工具 schema
|
|
88
|
+
|
|
89
|
+
#### 模型看到的内容
|
|
90
|
+
|
|
91
|
+
glob 描述声明了配置的超过上限排序方式。生成的 [`glob` 和 `grep` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-fs-search) 使用 `sampleOverCapGlobResults: true`;工具无条件注册。
|
|
92
|
+
|
|
93
|
+
#### Token 影响
|
|
94
|
+
|
|
95
|
+
工具可见时每个请求有固定的 schema 成本。
|
|
96
|
+
|
|
97
|
+
#### KV Cache 影响
|
|
98
|
+
|
|
99
|
+
工具可见性与定义不变时前缀稳定。注册生命周期或作用域限制可能从第一个改变的 schema token 起使复用失效。
|
|
100
|
+
|
|
101
|
+
### 结果与 spill 提示
|
|
102
|
+
|
|
103
|
+
#### 模型看到的内容
|
|
104
|
+
|
|
105
|
+
`glob` 每行返回一个路径;`grep` 在每个路径下分组展示 `Line <line>: <preview>` 匹配。空搜索返回 `No files found` 或 `No matches found`。达到上限的结果以省略计数结尾,并附 spill locator 与后端检索提示,或说明完整结果无法保存。启用 `sampleOverCapGlobResults: true` 时,超过上限的 `glob` 页面按实际搜索根正下方的条目轮转取路径,页脚说明采样依据及其覆盖的顶层条目数;无法覆盖全部条目时,页脚提示模型收窄 `path`。`false` 时页面是按修改时间排序的前部,并保留普通的上限结果页脚。未超过上限的结果原样呈现;扁平采样的结果也保留普通页脚,因为其采样等于按修改时间排序的前部。spill 产物始终持有按修改时间排序的完整列表。
|
|
106
|
+
|
|
107
|
+
#### Token 影响
|
|
108
|
+
|
|
109
|
+
内联路径与匹配受 `globMaxResults`、`grepMaxMatches` 与 `grepMaxLineBytes` 约束;调用及其保留结果在压缩(compaction)前留在历史中。
|
|
110
|
+
|
|
111
|
+
#### KV Cache 影响
|
|
112
|
+
|
|
113
|
+
只追加;新可见内容跟在可复用请求前缀之后,不会使既有 KV Cache 条目失效。
|
|
114
|
+
|
|
115
|
+
### 工具错误
|
|
116
|
+
|
|
117
|
+
#### 模型看到的内容
|
|
118
|
+
|
|
119
|
+
失败被规范化为 `Error: <message>`,并携带结构化 `SEARCH_INVALID_PATTERN`、`SEARCH_FAILED`、`SEARCH_RAW_OUTPUT_OVERFLOW` 或 `SEARCH_ABORTED` 元数据供调用方使用。
|
|
120
|
+
|
|
121
|
+
#### Token 影响
|
|
122
|
+
|
|
123
|
+
只有失败的调用会增加这些保留 token。
|
|
124
|
+
|
|
125
|
+
#### KV Cache 影响
|
|
126
|
+
|
|
127
|
+
只追加;新可见内容跟在可复用请求前缀之后,不会使既有 KV Cache 条目失效。
|
|
128
|
+
|
|
129
|
+
## 已知限制与暂缓事项
|
|
130
|
+
|
|
131
|
+
- **搜索与文件访问没有共享工作区证明**——只有当工作目录与文件系统根目录指向同一工作区时,返回路径才可继续读取;本包不执行运行时跨服务校验。
|
|
132
|
+
- **打包二进制固定在依赖版本上**——`@vscode/ripgrep` 覆盖其随附的平台(macOS/Linux/Windows,x64/arm64);不支持的平台或损坏的安装会以 `SEARCH_FAILED` 使调用失败。远程或虚拟文件系统需要共置的工作区或另一个搜索消费方。
|
|
133
|
+
- **schema 只暴露一个有界页面**——偏移分页、大小写开关、替代输出模式与提供方支撑的发现仍不在本包范围内;达到上限的完整输出需要 spill 后端。
|
|
134
|
+
- **启用采样时仅按搜索根正下方的第一段路径分组**——超过上限的 `glob` 页面在这些顶层条目之间平衡,因此集中在更深处的结果(一棵均匀树里某个繁忙目录)在该层级之下仍会呈现不均;递归平衡被延期。
|