@x1a0f3n9/dsh-tool-fs 0.1.5-rc.4 → 0.1.7-rc.2
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/README.i18n.yaml +141 -5
- package/README.md +4 -4
- package/README.zh.md +4 -4
- package/lib/index.js +26 -92
- package/lib/types/diff.d.ts +4 -1
- package/lib/types/read-render.d.ts +8 -5
- package/lib/types/sandbox.d.ts +2 -1
- package/lib/types/session-cwd.d.ts +2 -5
- package/package.json +33 -31
package/README.i18n.yaml
CHANGED
|
@@ -1,6 +1,142 @@
|
|
|
1
|
-
# Bilingual-pair consistency record (docs/i18n/README.md):
|
|
2
|
-
#
|
|
3
|
-
#
|
|
1
|
+
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
|
2
|
+
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
|
3
|
+
# After editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/fs/tool-fs/README.md
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/:
|
|
6
|
+
en: 52b93805befe8077
|
|
7
|
+
zh: 9786e662303f0e2f
|
|
8
|
+
/x1a0f3n9-dsh-tool-fs:
|
|
9
|
+
en: c53838f9abadf120
|
|
10
|
+
zh: e65d8cbc2c3a6691
|
|
11
|
+
/x1a0f3n9-dsh-tool-fs/summary:
|
|
12
|
+
en: c8f608c85c8d6626
|
|
13
|
+
zh: 4133a867517baca5
|
|
14
|
+
/x1a0f3n9-dsh-tool-fs/table-of-contents:
|
|
15
|
+
en: d152484eb41ac6b4
|
|
16
|
+
zh: 09388d293f9be9cb
|
|
17
|
+
/x1a0f3n9-dsh-tool-fs/use-this-package:
|
|
18
|
+
en: 8fd62afcdabe55d4
|
|
19
|
+
zh: 9bdcae272575be8c
|
|
20
|
+
/x1a0f3n9-dsh-tool-fs/use-this-package/minimal-composition:
|
|
21
|
+
en: eb21d89a3ecbd2d4
|
|
22
|
+
zh: f05ccbb1e7515f32
|
|
23
|
+
/x1a0f3n9-dsh-tool-fs/use-this-package/the-tools:
|
|
24
|
+
en: e70e0164411016b5
|
|
25
|
+
zh: 3fa6caa8f3d70552
|
|
26
|
+
/x1a0f3n9-dsh-tool-fs/use-this-package/configuration:
|
|
27
|
+
en: 7eb705e3b132fcba
|
|
28
|
+
zh: 883207b13d381f9e
|
|
29
|
+
/x1a0f3n9-dsh-tool-fs/use-this-package/policy-and-sandbox-behavior:
|
|
30
|
+
en: 53d4ac2db089ef39
|
|
31
|
+
zh: 214ea051ed56f500
|
|
32
|
+
/x1a0f3n9-dsh-tool-fs/use-this-package/failures-and-recovery:
|
|
33
|
+
en: 962b09e21305a04b
|
|
34
|
+
zh: 382d2b8cce217569
|
|
35
|
+
/x1a0f3n9-dsh-tool-fs/understand-the-implementation:
|
|
36
|
+
en: e30f7038c28e93f8
|
|
37
|
+
zh: a3868dbd90367b13
|
|
38
|
+
/x1a0f3n9-dsh-tool-fs/understand-the-implementation/design-concept:
|
|
39
|
+
en: 454b5291db9ba847
|
|
40
|
+
zh: 9fe7081dfb416c93
|
|
41
|
+
/x1a0f3n9-dsh-tool-fs/understand-the-implementation/source-map:
|
|
42
|
+
en: e8220ed04480aadc
|
|
43
|
+
zh: 1cc5f9a505953102
|
|
44
|
+
/x1a0f3n9-dsh-tool-fs/understand-the-implementation/per-tool-flow:
|
|
45
|
+
en: d741e01be9fddb76
|
|
46
|
+
zh: 7aa1d7ca719a4aac
|
|
47
|
+
/x1a0f3n9-dsh-tool-fs/understand-the-implementation/observation-and-concurrency:
|
|
48
|
+
en: 665d437dc35bf05f
|
|
49
|
+
zh: 8004334d6a3246b4
|
|
50
|
+
/x1a0f3n9-dsh-tool-fs/further-exploration:
|
|
51
|
+
en: 485bc55482f576bc
|
|
52
|
+
zh: fc5fa55b41098bd0
|
|
53
|
+
/x1a0f3n9-dsh-tool-fs/model-experience:
|
|
54
|
+
en: 215e7ba838619b7b
|
|
55
|
+
zh: a311da3843709f90
|
|
56
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/system-prompt:
|
|
57
|
+
en: cf78b9dd5596495f
|
|
58
|
+
zh: bd44560f8c2435e8
|
|
59
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/system-prompt/what-the-model-sees:
|
|
60
|
+
en: b09ee4be5e522c29
|
|
61
|
+
zh: ffd30b57d7fc96e8
|
|
62
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/system-prompt/what-the-model-sees/read-guidance:
|
|
63
|
+
en: f8961df3f3a6a671
|
|
64
|
+
zh: 85c7bd418b40b089
|
|
65
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/system-prompt/what-the-model-sees/write-guidance:
|
|
66
|
+
en: 7e34af48c583f210
|
|
67
|
+
zh: e39ad6823689c665
|
|
68
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/system-prompt/what-the-model-sees/edit-guidance:
|
|
69
|
+
en: 28f07502a411303b
|
|
70
|
+
zh: 437897dc99fc4360
|
|
71
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/system-prompt/token-effect:
|
|
72
|
+
en: 7a44cabe439a879a
|
|
73
|
+
zh: 1adf9bf3de7658b6
|
|
74
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/system-prompt/kv-cache-effect:
|
|
75
|
+
en: 4f1b5639f91405a8
|
|
76
|
+
zh: f90ffe077a2e52a3
|
|
77
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-schemas:
|
|
78
|
+
en: 3039bc5e7a796b21
|
|
79
|
+
zh: 6b7a9eaf69c9ea53
|
|
80
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-schemas/what-the-model-sees:
|
|
81
|
+
en: 6f2a072c474e39e7
|
|
82
|
+
zh: dbee4c2b206bf68f
|
|
83
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-schemas/token-effect:
|
|
84
|
+
en: 68517f7d65ef7e9d
|
|
85
|
+
zh: 544a4b81e8ea16c0
|
|
86
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-schemas/kv-cache-effect:
|
|
87
|
+
en: 1e6d3da20012762d
|
|
88
|
+
zh: 482f8bc569b8b490
|
|
89
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/read-result:
|
|
90
|
+
en: ebd38733c0490428
|
|
91
|
+
zh: b45101c325efe784
|
|
92
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/read-result/what-the-model-sees:
|
|
93
|
+
en: 06e250bd8788248a
|
|
94
|
+
zh: e00d36b48068909a
|
|
95
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/read-result/token-effect:
|
|
96
|
+
en: 4269b4368622ec2f
|
|
97
|
+
zh: f4df80c1fb6972f1
|
|
98
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/read-result/kv-cache-effect:
|
|
99
|
+
en: f5d5f97a153f7c70
|
|
100
|
+
zh: 3d6bc05b9eadfbc2
|
|
101
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/image-read-result:
|
|
102
|
+
en: 9dac44e6d0b9d8de
|
|
103
|
+
zh: 7bc4dc1c5df39eaf
|
|
104
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/image-read-result/what-the-model-sees:
|
|
105
|
+
en: 9252b6d73776c5ff
|
|
106
|
+
zh: d6e433450989399e
|
|
107
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/image-read-result/token-effect:
|
|
108
|
+
en: 68bd5255f1c9ca48
|
|
109
|
+
zh: 0474213531c1aae3
|
|
110
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/image-read-result/kv-cache-effect:
|
|
111
|
+
en: f5d5f97a153f7c70
|
|
112
|
+
zh: 48e202e396bc5fcc
|
|
113
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/write-and-edit-results:
|
|
114
|
+
en: 1b3b6cfa3605d0b4
|
|
115
|
+
zh: 78e37c2aa4f76d54
|
|
116
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/write-and-edit-results/what-the-model-sees:
|
|
117
|
+
en: bb2a92e0e43e3273
|
|
118
|
+
zh: a744395576b48a93
|
|
119
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/write-and-edit-results/token-effect:
|
|
120
|
+
en: fb4d0b17a99f49cf
|
|
121
|
+
zh: 17460a2a5d72f6cc
|
|
122
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/write-and-edit-results/kv-cache-effect:
|
|
123
|
+
en: f5d5f97a153f7c70
|
|
124
|
+
zh: 3d6bc05b9eadfbc2
|
|
125
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-errors:
|
|
126
|
+
en: 2d4f2c8605eccab3
|
|
127
|
+
zh: 67f1f0218f73c6bf
|
|
128
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-errors/what-the-model-sees:
|
|
129
|
+
en: 4e8fac7bac8ced61
|
|
130
|
+
zh: 7ba921dbcddc9f97
|
|
131
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-errors/token-effect:
|
|
132
|
+
en: 681cadd5be7b8ac1
|
|
133
|
+
zh: 65e483f62fb819d9
|
|
134
|
+
/x1a0f3n9-dsh-tool-fs/model-experience/tool-errors/kv-cache-effect:
|
|
135
|
+
en: f5d5f97a153f7c70
|
|
136
|
+
zh: 3d6bc05b9eadfbc2
|
|
137
|
+
/x1a0f3n9-dsh-tool-fs/known-limitations-and-deferred-work:
|
|
138
|
+
en: ce7a91d41d2f7597
|
|
139
|
+
zh: d4a3c905e124fd7f
|
|
140
|
+
/x1a0f3n9-dsh-tool-fs/known-limitations-and-deferred-work/dev-note:
|
|
141
|
+
en: 0c4d0c465413d319
|
|
142
|
+
zh: a20efeb10121b927
|
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-a
|
|
|
67
67
|
|
|
68
68
|
Path authorization for `read` and `read_image` belongs entirely to `ctx.fs`; media-type declarations and file signatures only decide whether `read_image` accepts the bytes returned by that backend.
|
|
69
69
|
|
|
70
|
-
With the policy plugin mounted, `write` and `edit` obtain their guard from the `fs/*` intent slots, so an unread target or a stale observation fails with `FS_NOT_OBSERVED` or `FS_STALE_VERSION` and a recovery instruction. Under a confining backend (`fs-sandbox`), `write`/`edit` additionally advertise `sandbox_permissions` and `justification`; a denied mutation returns the `[sandbox: file access denied under <mode> mode]` marker with the same-turn escalation hint, and an approved retry may stamp a strictly wider mode for that one call.
|
|
70
|
+
With the policy plugin mounted, `write` and `edit` obtain their guard from the `fs/*` intent slots, so an unread target or a stale observation fails with `FS_NOT_OBSERVED` or `FS_STALE_VERSION` and a recovery instruction. Under a confining backend (`fs-sandbox`), `write`/`edit` additionally advertise `sandbox_permissions` and `justification`; a denied mutation returns the `[sandbox: file access denied under <mode> mode]` marker with the same-turn escalation hint, and an approved retry may stamp a strictly wider mode for that one call. The justification asks the model to use the language of the current user request.
|
|
71
71
|
|
|
72
72
|
### Failures and recovery
|
|
73
73
|
|
|
@@ -138,19 +138,19 @@ At assembly time, each guidance section checks `ctx.tools.get(name, scope)` and
|
|
|
138
138
|
##### Read guidance
|
|
139
139
|
|
|
140
140
|
```markdown
|
|
141
|
-
Use the read tool — not shell commands like cat — to inspect text files.
|
|
141
|
+
Use the read tool — not shell commands like cat — to inspect text files. Use offset and limit to continue reading large files.
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
##### Write guidance
|
|
145
145
|
|
|
146
146
|
```markdown
|
|
147
|
-
|
|
147
|
+
Read an existing file before overwriting it with write (the default fs-observation-policy requires it) and prefer edit for targeted changes.
|
|
148
148
|
```
|
|
149
149
|
|
|
150
150
|
##### Edit guidance
|
|
151
151
|
|
|
152
152
|
```markdown
|
|
153
|
-
|
|
153
|
+
Read a file before editing it (the default fs-observation-policy requires it), unless you just created or edited it in this session.
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
#### Token effect
|
package/README.zh.md
CHANGED
|
@@ -67,7 +67,7 @@ kind: "package-reference"
|
|
|
67
67
|
|
|
68
68
|
`read` 与 `read_image` 的路径授权完全由 `ctx.fs` 负责;媒体类型声明和文件签名只决定 `read_image` 是否接受该后端返回的字节。
|
|
69
69
|
|
|
70
|
-
挂载策略插件后,`write` 与 `edit` 从 `fs/*` 意图槽位取得防护,因此未读目标或陈旧观察会以 `FS_NOT_OBSERVED` 或 `FS_STALE_VERSION` 及恢复指令失败。使用施加沙箱限制的后端(`fs-sandbox`)时,`write`/`edit` 还会公开 `sandbox_permissions` 与 `justification`;被拒绝的变更返回 `[sandbox: file access denied under <mode> mode]`
|
|
70
|
+
挂载策略插件后,`write` 与 `edit` 从 `fs/*` 意图槽位取得防护,因此未读目标或陈旧观察会以 `FS_NOT_OBSERVED` 或 `FS_STALE_VERSION` 及恢复指令失败。使用施加沙箱限制的后端(`fs-sandbox`)时,`write`/`edit` 还会公开 `sandbox_permissions` 与 `justification`;被拒绝的变更返回 `[sandbox: file access denied under <mode> mode]` 标记与同轮次升级提示,获批的重试可以在该次调用中加盖严格更宽的模式。理由字段提示模型使用用户当前提问的语言。
|
|
71
71
|
|
|
72
72
|
### 失败与恢复
|
|
73
73
|
|
|
@@ -138,19 +138,19 @@ kind: "package-reference"
|
|
|
138
138
|
##### Read 指导
|
|
139
139
|
|
|
140
140
|
```markdown
|
|
141
|
-
Use the read tool — not shell commands like cat — to inspect text files.
|
|
141
|
+
Use the read tool — not shell commands like cat — to inspect text files. Use offset and limit to continue reading large files.
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
##### Write 指导
|
|
145
145
|
|
|
146
146
|
```markdown
|
|
147
|
-
|
|
147
|
+
Read an existing file before overwriting it with write (the default fs-observation-policy requires it) and prefer edit for targeted changes.
|
|
148
148
|
```
|
|
149
149
|
|
|
150
150
|
##### Edit 指导
|
|
151
151
|
|
|
152
152
|
```markdown
|
|
153
|
-
|
|
153
|
+
Read a file before editing it (the default fs-observation-policy requires it), unless you just created or edited it in this session.
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
#### Token 影响
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
2
|
import { defineTool } from "@x1a0f3n9/dsh-tools";
|
|
3
3
|
import { FsError } from "@x1a0f3n9/dsh-fs";
|
|
4
|
-
import {
|
|
4
|
+
import { readLangHintForPath as langFromPath } from "@x1a0f3n9/dsh-util-code-language";
|
|
5
5
|
import { structuredPatch } from "diff";
|
|
6
6
|
import { basename, extname } from "node:path";
|
|
7
7
|
import { AttachmentError, AttachmentId } from "@x1a0f3n9/dsh-attachment";
|
|
8
|
+
import { ESCALATION_TARGETS, approveEscalation, escalationHintMarker, sandboxDenialMarker, sandboxPermissionsDescription, validateEscalationArgs } from "@x1a0f3n9/dsh-sandbox";
|
|
8
9
|
//#region lib/types/read-render.js
|
|
9
10
|
/**
|
|
10
11
|
* Pure read presentation: turn provider-decoded text into a bounded, line-numbered window and
|
|
@@ -110,71 +111,6 @@ ${outcome.lines.length > 0 ? `${outcome.lines.map((line) => `${line.number}: ${l
|
|
|
110
111
|
</content>`;
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
113
|
-
* Lowercased file-extension to syntax-highlighting language hint. Keys are the
|
|
114
|
-
* extension without its dot; a UI treats an absent key as plain text. The map is
|
|
115
|
-
* intentionally small — common source, config, and markup extensions a
|
|
116
|
-
* line-numbered code view benefits from highlighting — not an exhaustive registry.
|
|
117
|
-
*/
|
|
118
|
-
const LANG_BY_EXTENSION = {
|
|
119
|
-
ts: "ts",
|
|
120
|
-
tsx: "tsx",
|
|
121
|
-
mts: "ts",
|
|
122
|
-
cts: "ts",
|
|
123
|
-
js: "js",
|
|
124
|
-
jsx: "jsx",
|
|
125
|
-
mjs: "js",
|
|
126
|
-
cjs: "js",
|
|
127
|
-
json: "json",
|
|
128
|
-
jsonc: "json",
|
|
129
|
-
py: "py",
|
|
130
|
-
rb: "rb",
|
|
131
|
-
go: "go",
|
|
132
|
-
rs: "rs",
|
|
133
|
-
java: "java",
|
|
134
|
-
c: "c",
|
|
135
|
-
h: "c",
|
|
136
|
-
cc: "cpp",
|
|
137
|
-
cpp: "cpp",
|
|
138
|
-
hpp: "cpp",
|
|
139
|
-
cxx: "cpp",
|
|
140
|
-
cs: "cs",
|
|
141
|
-
kt: "kotlin",
|
|
142
|
-
swift: "swift",
|
|
143
|
-
php: "php",
|
|
144
|
-
sh: "sh",
|
|
145
|
-
bash: "sh",
|
|
146
|
-
zsh: "sh",
|
|
147
|
-
yaml: "yaml",
|
|
148
|
-
yml: "yaml",
|
|
149
|
-
toml: "toml",
|
|
150
|
-
ini: "ini",
|
|
151
|
-
md: "md",
|
|
152
|
-
markdown: "md",
|
|
153
|
-
mdx: "mdx",
|
|
154
|
-
html: "html",
|
|
155
|
-
htm: "html",
|
|
156
|
-
css: "css",
|
|
157
|
-
scss: "scss",
|
|
158
|
-
less: "less",
|
|
159
|
-
sql: "sql",
|
|
160
|
-
xml: "xml",
|
|
161
|
-
lua: "lua"
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* Derive a syntax-highlighting language hint from a read path's file extension.
|
|
165
|
-
* Pure and case-insensitive on the extension; a dotfile with no extension
|
|
166
|
-
* (`.gitignore`) and an unknown extension both yield `undefined`.
|
|
167
|
-
* @param path - the model-facing path the read reported.
|
|
168
|
-
* @returns the language hint for {@link LANG_BY_EXTENSION}, or `undefined` when the extension maps to none.
|
|
169
|
-
*/
|
|
170
|
-
function langFromPath(path) {
|
|
171
|
-
const base = path.slice(Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")) + 1);
|
|
172
|
-
const dot = base.lastIndexOf(".");
|
|
173
|
-
if (dot <= 0) return void 0;
|
|
174
|
-
const ext = base.slice(dot + 1).toLowerCase();
|
|
175
|
-
return Object.hasOwn(LANG_BY_EXTENSION, ext) ? LANG_BY_EXTENSION[ext] : void 0;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
114
|
* Whether `value` is a valid {@link FileTextLine} (defensive narrowing from
|
|
179
115
|
* opaque `meta`). `number` must be a 1-based integer line number, since a card
|
|
180
116
|
* rendered from a zero, fractional, or non-finite line number would violate the
|
|
@@ -229,28 +165,22 @@ function readMetaFromMeta(meta) {
|
|
|
229
165
|
* `process.cwd()` at the tool boundary.
|
|
230
166
|
* @module @x1a0f3n9/dsh-tool-fs/session-cwd
|
|
231
167
|
*/
|
|
232
|
-
const PARENT_PATH_SEGMENT = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
|
|
233
168
|
/**
|
|
234
169
|
* The session workspace cwd for this call, or `undefined` when none applies.
|
|
235
170
|
* @param exec - the tool-execution context; only its optional `agent` is read.
|
|
236
|
-
* @param requestedPath - the path the provider will resolve; parent traversal
|
|
237
|
-
* makes a symlinked cwd's filesystem identity observable.
|
|
238
171
|
* @returns the calling agent's session cwd, or undefined for a non-agent caller (the backend then applies its own default).
|
|
239
172
|
*/
|
|
240
|
-
function sessionCwd(exec
|
|
241
|
-
|
|
242
|
-
if (cwd === void 0 || !PARENT_PATH_SEGMENT.test(cwd) && !PARENT_PATH_SEGMENT.test(requestedPath)) return cwd;
|
|
243
|
-
return canonicalPath(cwd);
|
|
173
|
+
function sessionCwd(exec) {
|
|
174
|
+
return exec.agent?.session.header.cwd;
|
|
244
175
|
}
|
|
245
176
|
/**
|
|
246
177
|
* Resolution options shared by all model-facing filesystem tools.
|
|
247
178
|
* @param exec - the tool-execution context supplying session cwd and cancellation.
|
|
248
|
-
* @param requestedPath - the path the provider will resolve.
|
|
249
179
|
* @param policyWorkspaceRoot - resolved per-call root, when a mutation carries sandbox policy.
|
|
250
180
|
* @returns provider resolution options for the current tool call.
|
|
251
181
|
*/
|
|
252
|
-
function sessionResolveOptions(exec,
|
|
253
|
-
const cwd = policyWorkspaceRoot ?? sessionCwd(exec
|
|
182
|
+
function sessionResolveOptions(exec, policyWorkspaceRoot) {
|
|
183
|
+
const cwd = policyWorkspaceRoot ?? sessionCwd(exec);
|
|
254
184
|
return {
|
|
255
185
|
...cwd !== void 0 ? { cwd } : {},
|
|
256
186
|
signal: exec.signal
|
|
@@ -270,7 +200,7 @@ function sessionResolveOptions(exec, requestedPath, policyWorkspaceRoot) {
|
|
|
270
200
|
* @returns the resolved target and its single stat result.
|
|
271
201
|
*/
|
|
272
202
|
async function resolveRegularReadTarget(ctx, exec, requestedPath) {
|
|
273
|
-
const target = await ctx.fs.resolve(requestedPath, sessionResolveOptions(exec
|
|
203
|
+
const target = await ctx.fs.resolve(requestedPath, sessionResolveOptions(exec));
|
|
274
204
|
const info = await ctx.fs.stat(target, exec.signal);
|
|
275
205
|
if (info === void 0) {
|
|
276
206
|
ctx.emit("fs/observed", target, { kind: "absent" }, exec);
|
|
@@ -326,7 +256,7 @@ function applyReadTool(ctx, caps) {
|
|
|
326
256
|
ctx.systemPrompt.section({
|
|
327
257
|
name: "tool:read",
|
|
328
258
|
order: ctx.systemPrompt.getSectionOrder("TOOL_READ"),
|
|
329
|
-
text: ({ scope }) => ctx.tools.get("read", scope) === void 0 ? "" : "Use the read tool — not shell commands like cat — to inspect text files.
|
|
259
|
+
text: ({ scope }) => ctx.tools.get("read", scope) === void 0 ? "" : "Use the read tool — not shell commands like cat — to inspect text files. Use offset and limit to continue reading large files."
|
|
330
260
|
});
|
|
331
261
|
ctx.tools.register(defineTool({
|
|
332
262
|
name: "read",
|
|
@@ -591,7 +521,7 @@ function applyWriteTool(ctx, sandbox) {
|
|
|
591
521
|
ctx.systemPrompt.section({
|
|
592
522
|
name: "tool:write",
|
|
593
523
|
order: ctx.systemPrompt.getSectionOrder("TOOL_WRITE"),
|
|
594
|
-
text: ({ scope }) => ctx.tools.get("write", scope) === void 0 ? "" : "
|
|
524
|
+
text: ({ scope }) => ctx.tools.get("write", scope) === void 0 ? "" : "Read an existing file before overwriting it with write (the default fs-observation-policy requires it)" + (ctx.tools.get("edit", scope) === void 0 ? "" : " and prefer edit for targeted changes") + "."
|
|
595
525
|
});
|
|
596
526
|
ctx.tools.register(defineTool({
|
|
597
527
|
name: "write",
|
|
@@ -637,16 +567,19 @@ function applyWriteTool(ctx, sandbox) {
|
|
|
637
567
|
type: "text",
|
|
638
568
|
text: formatWriteOutput(value.path, value)
|
|
639
569
|
}],
|
|
640
|
-
presentationMeta: (args, value) => ({
|
|
641
|
-
|
|
642
|
-
oldText,
|
|
643
|
-
|
|
644
|
-
|
|
570
|
+
presentationMeta: (args, value) => ({
|
|
571
|
+
operation: value.operation,
|
|
572
|
+
diffs: value.before === null ? [] : computeHunkDiffs(args.file_path, value.before, value.after).map(({ path, oldText, newText }) => ({
|
|
573
|
+
path,
|
|
574
|
+
oldText,
|
|
575
|
+
newText
|
|
576
|
+
}))
|
|
577
|
+
})
|
|
645
578
|
},
|
|
646
579
|
async execute(args, exec) {
|
|
647
580
|
const input = parseWriteArgs(args);
|
|
648
581
|
const sandboxPolicy = await sandbox.resolvePolicy("write", args, exec);
|
|
649
|
-
const target = await ctx.fs.resolve(input.filePath, sessionResolveOptions(exec,
|
|
582
|
+
const target = await ctx.fs.resolve(input.filePath, sessionResolveOptions(exec, sandboxPolicy?.workspaceRoot));
|
|
650
583
|
const intent = await ctx.waterfall("fs/write-intent", target, exec, () => void 0);
|
|
651
584
|
let outcome;
|
|
652
585
|
try {
|
|
@@ -736,7 +669,7 @@ function applyEditTool(ctx, sandbox) {
|
|
|
736
669
|
ctx.systemPrompt.section({
|
|
737
670
|
name: "tool:edit",
|
|
738
671
|
order: ctx.systemPrompt.getSectionOrder("TOOL_EDIT"),
|
|
739
|
-
text: ({ scope }) => ctx.tools.get("edit", scope) === void 0 ? "" : "
|
|
672
|
+
text: ({ scope }) => ctx.tools.get("edit", scope) === void 0 ? "" : "Read a file before editing it (the default fs-observation-policy requires it), unless you just created or edited it in this session."
|
|
740
673
|
});
|
|
741
674
|
ctx.tools.register(defineTool({
|
|
742
675
|
name: "edit",
|
|
@@ -750,7 +683,7 @@ function applyEditTool(ctx, sandbox) {
|
|
|
750
683
|
old_string: {
|
|
751
684
|
type: "string",
|
|
752
685
|
required: true,
|
|
753
|
-
description: "Literal text to replace.
|
|
686
|
+
description: "Literal text to replace."
|
|
754
687
|
},
|
|
755
688
|
new_string: {
|
|
756
689
|
type: "string",
|
|
@@ -795,7 +728,7 @@ function applyEditTool(ctx, sandbox) {
|
|
|
795
728
|
async execute(args, exec) {
|
|
796
729
|
const input = parseEditArgs(args);
|
|
797
730
|
const sandboxPolicy = await sandbox.resolvePolicy("edit", args, exec);
|
|
798
|
-
const target = await ctx.fs.resolve(input.filePath, sessionResolveOptions(exec,
|
|
731
|
+
const target = await ctx.fs.resolve(input.filePath, sessionResolveOptions(exec, sandboxPolicy?.workspaceRoot));
|
|
799
732
|
let outcome;
|
|
800
733
|
try {
|
|
801
734
|
const intent = await ctx.waterfall("fs/edit-intent", target, exec, () => void 0);
|
|
@@ -1040,7 +973,7 @@ function imageReadContent(value) {
|
|
|
1040
973
|
function applyReadImageTool(ctx) {
|
|
1041
974
|
ctx.tools.register(defineTool({
|
|
1042
975
|
name: "read_image",
|
|
1043
|
-
description: "Read a PNG/JPEG/WebP/GIF file and return the image itself.
|
|
976
|
+
description: "Read a PNG/JPEG/WebP/GIF file and return the image itself. Large images are downscaled automatically; do not install image libraries or create thumbnails to inspect an image.",
|
|
1044
977
|
parameters: { file_path: {
|
|
1045
978
|
type: "string",
|
|
1046
979
|
required: true,
|
|
@@ -1165,18 +1098,19 @@ var FsSandboxController = class {
|
|
|
1165
1098
|
sandbox_permissions: {
|
|
1166
1099
|
type: "string",
|
|
1167
1100
|
enum: [...this.escalationModes],
|
|
1168
|
-
description: "
|
|
1101
|
+
description: sandboxPermissionsDescription("operation")
|
|
1169
1102
|
},
|
|
1170
1103
|
justification: {
|
|
1171
1104
|
type: "string",
|
|
1172
|
-
description: "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access."
|
|
1105
|
+
description: "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access. Use the language of the user’s current request."
|
|
1173
1106
|
}
|
|
1174
1107
|
};
|
|
1175
1108
|
}
|
|
1176
1109
|
/**
|
|
1177
1110
|
* The policy to stamp onto this mutation: an approved escalation grant (a
|
|
1178
1111
|
* strictly wider retry resolved through `ctx.approval` before anything
|
|
1179
|
-
* executes), else the session's standing mode.
|
|
1112
|
+
* executes), else the session's standing mode. Repeating the standing mode
|
|
1113
|
+
* requires no approval. The calling session's cwd is
|
|
1180
1114
|
* always carried as the workspace root. Validates the escalation argument
|
|
1181
1115
|
* pairing first.
|
|
1182
1116
|
* @param toolName - the mutating tool's name, for the approval audit trail.
|
package/lib/types/diff.d.ts
CHANGED
|
@@ -8,13 +8,16 @@ import type { FileDiff } from '@x1a0f3n9/dsh-tools';
|
|
|
8
8
|
export declare const DIFF_CONTEXT = 3;
|
|
9
9
|
/**
|
|
10
10
|
* The `write`/`edit` tools' private `tool/result` `meta` payload: the applied
|
|
11
|
-
* contextual-diff hunks
|
|
11
|
+
* contextual-diff hunks, and for `write` whether the call created or updated
|
|
12
|
+
* the file, which tells an empty hunk list of a create from one of an
|
|
13
|
+
* unchanged overwrite. Attached opaquely (as `unknown`) on the tool result and
|
|
12
14
|
* persisted with the session log — it must be JSON-serializable (the session
|
|
13
15
|
* validates this at `append`), so `presentResult` reproduces the diff card on
|
|
14
16
|
* replay. The producing tool owns and narrows this opaque shape.
|
|
15
17
|
*/
|
|
16
18
|
export type FsDiffMeta = {
|
|
17
19
|
diffs: FileDiff[];
|
|
20
|
+
operation?: 'create' | 'update';
|
|
18
21
|
};
|
|
19
22
|
/**
|
|
20
23
|
* Compute one {@link FileDiff} per hunk between `before` and `after`, each carrying the
|
|
@@ -64,13 +64,16 @@ export declare function buildWindow(chunks: AsyncIterable<string> | Iterable<str
|
|
|
64
64
|
*/
|
|
65
65
|
export declare function formatReadOutput(displayPath: string, outcome: FileReadOutcome): string;
|
|
66
66
|
/**
|
|
67
|
-
* Derive
|
|
68
|
-
*
|
|
69
|
-
* (
|
|
67
|
+
* Derive the persisted `lang` hint from a read path's file extension. The shared
|
|
68
|
+
* table in `@x1a0f3n9/dsh-util-code-language` owns the recognized suffixes and
|
|
69
|
+
* the path rules (both separators, a leading dot as the extension separator, and
|
|
70
|
+
* prototype-key safety); `readLangHintForPath` projects the read card's short ids
|
|
71
|
+
* over it, so a suffix whose value a recorded session already holds keeps it
|
|
72
|
+
* byte-identical while every other suffix uses its language's short name.
|
|
70
73
|
* @param path - the model-facing path the read reported.
|
|
71
|
-
* @returns the language hint
|
|
74
|
+
* @returns the persisted language hint, or `undefined` when the extension maps to none.
|
|
72
75
|
*/
|
|
73
|
-
export
|
|
76
|
+
export { readLangHintForPath as langFromPath } from '@x1a0f3n9/dsh-util-code-language';
|
|
74
77
|
/**
|
|
75
78
|
* The `read` tool's private `tool/result` `meta` payload: the structured
|
|
76
79
|
* line-numbered window a capable UI renders as a code view. Attached opaquely (as
|
package/lib/types/sandbox.d.ts
CHANGED
|
@@ -52,7 +52,8 @@ export declare class FsSandboxController {
|
|
|
52
52
|
/**
|
|
53
53
|
* The policy to stamp onto this mutation: an approved escalation grant (a
|
|
54
54
|
* strictly wider retry resolved through `ctx.approval` before anything
|
|
55
|
-
* executes), else the session's standing mode.
|
|
55
|
+
* executes), else the session's standing mode. Repeating the standing mode
|
|
56
|
+
* requires no approval. The calling session's cwd is
|
|
56
57
|
* always carried as the workspace root. Validates the escalation argument
|
|
57
58
|
* pairing first.
|
|
58
59
|
* @param toolName - the mutating tool's name, for the approval audit trail.
|
|
@@ -10,19 +10,16 @@ import type { ToolExecution } from '@x1a0f3n9/dsh-tools';
|
|
|
10
10
|
/**
|
|
11
11
|
* The session workspace cwd for this call, or `undefined` when none applies.
|
|
12
12
|
* @param exec - the tool-execution context; only its optional `agent` is read.
|
|
13
|
-
* @param requestedPath - the path the provider will resolve; parent traversal
|
|
14
|
-
* makes a symlinked cwd's filesystem identity observable.
|
|
15
13
|
* @returns the calling agent's session cwd, or undefined for a non-agent caller (the backend then applies its own default).
|
|
16
14
|
*/
|
|
17
|
-
export declare function sessionCwd(exec: ToolExecution
|
|
15
|
+
export declare function sessionCwd(exec: ToolExecution): string | undefined;
|
|
18
16
|
/**
|
|
19
17
|
* Resolution options shared by all model-facing filesystem tools.
|
|
20
18
|
* @param exec - the tool-execution context supplying session cwd and cancellation.
|
|
21
|
-
* @param requestedPath - the path the provider will resolve.
|
|
22
19
|
* @param policyWorkspaceRoot - resolved per-call root, when a mutation carries sandbox policy.
|
|
23
20
|
* @returns provider resolution options for the current tool call.
|
|
24
21
|
*/
|
|
25
|
-
export declare function sessionResolveOptions(exec: ToolExecution,
|
|
22
|
+
export declare function sessionResolveOptions(exec: ToolExecution, policyWorkspaceRoot?: string): {
|
|
26
23
|
cwd?: string;
|
|
27
24
|
signal?: AbortSignal;
|
|
28
25
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x1a0f3n9/dsh-tool-fs",
|
|
3
3
|
"description": "Model-facing filesystem tools (read, write, edit) over the DeepSeek Harness filesystem seam (ctx.fs)",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.7-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -28,39 +28,41 @@
|
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"diff": "^9.0.0",
|
|
31
|
-
"@deepseek-ai/schemastery": "
|
|
31
|
+
"@deepseek-ai/schemastery": "~3.18.4",
|
|
32
|
+
"@x1a0f3n9/dsh-util-code-language": "0.1.7-rc.2"
|
|
32
33
|
},
|
|
33
34
|
"peerDependencies": {
|
|
34
|
-
"@x1a0f3n9/dsh-attachment": "
|
|
35
|
-
"@x1a0f3n9/dsh-fs": "
|
|
36
|
-
"@x1a0f3n9/dsh-llm": "
|
|
37
|
-
"@x1a0f3n9/dsh-sandbox": "
|
|
38
|
-
"@x1a0f3n9/dsh-sandbox-policy": "
|
|
39
|
-
"@x1a0f3n9/dsh-session": "
|
|
40
|
-
"@x1a0f3n9/dsh-system-prompt": "
|
|
41
|
-
"@x1a0f3n9/dsh-tools": "
|
|
42
|
-
"@x1a0f3n9/dsh-user-approval": "
|
|
43
|
-
"@deepseek-ai/cordis": "
|
|
35
|
+
"@x1a0f3n9/dsh-attachment": "0.1.7-rc.2",
|
|
36
|
+
"@x1a0f3n9/dsh-fs": "0.1.7-rc.2",
|
|
37
|
+
"@x1a0f3n9/dsh-llm": "0.1.7-rc.2",
|
|
38
|
+
"@x1a0f3n9/dsh-sandbox": "0.1.7-rc.2",
|
|
39
|
+
"@x1a0f3n9/dsh-sandbox-policy": "0.1.7-rc.2",
|
|
40
|
+
"@x1a0f3n9/dsh-session": "0.1.7-rc.2",
|
|
41
|
+
"@x1a0f3n9/dsh-system-prompt": "0.1.7-rc.2",
|
|
42
|
+
"@x1a0f3n9/dsh-tools": "0.1.7-rc.2",
|
|
43
|
+
"@x1a0f3n9/dsh-user-approval": "0.1.7-rc.2",
|
|
44
|
+
"@deepseek-ai/cordis": "~4.0.4"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
|
-
"@x1a0f3n9/dsh-agent
|
|
47
|
-
"@x1a0f3n9/dsh-agent": "
|
|
48
|
-
"@x1a0f3n9/dsh-agent-loop-testkit": "
|
|
49
|
-
"@x1a0f3n9/dsh-attachment": "
|
|
50
|
-
"@x1a0f3n9/dsh-fs": "
|
|
51
|
-
"@x1a0f3n9/dsh-fs-local": "
|
|
52
|
-
"@x1a0f3n9/dsh-fs-observation-policy": "
|
|
53
|
-
"@x1a0f3n9/dsh-llm": "
|
|
54
|
-
"@x1a0f3n9/dsh-llm-deepseek": "
|
|
55
|
-
"@x1a0f3n9/dsh-
|
|
56
|
-
"@x1a0f3n9/dsh-sandbox
|
|
57
|
-
"@x1a0f3n9/dsh-
|
|
58
|
-
"@x1a0f3n9/dsh-
|
|
59
|
-
"@x1a0f3n9/dsh-
|
|
60
|
-
"@x1a0f3n9/dsh-
|
|
61
|
-
"@
|
|
62
|
-
"@
|
|
63
|
-
"@x1a0f3n9/dsh-
|
|
64
|
-
"@x1a0f3n9/dsh-
|
|
47
|
+
"@x1a0f3n9/dsh-agent": "0.1.7-rc.2",
|
|
48
|
+
"@x1a0f3n9/dsh-agent-loop": "0.1.7-rc.2",
|
|
49
|
+
"@x1a0f3n9/dsh-agent-loop-testkit": "0.1.7-rc.2",
|
|
50
|
+
"@x1a0f3n9/dsh-attachment": "0.1.7-rc.2",
|
|
51
|
+
"@x1a0f3n9/dsh-fs": "0.1.7-rc.2",
|
|
52
|
+
"@x1a0f3n9/dsh-fs-local": "0.1.7-rc.2",
|
|
53
|
+
"@x1a0f3n9/dsh-fs-observation-policy": "0.1.7-rc.2",
|
|
54
|
+
"@x1a0f3n9/dsh-llm": "0.1.7-rc.2",
|
|
55
|
+
"@x1a0f3n9/dsh-llm-deepseek": "0.1.7-rc.2",
|
|
56
|
+
"@x1a0f3n9/dsh-llm-deepseek-api-key": "0.1.7-rc.2",
|
|
57
|
+
"@x1a0f3n9/dsh-sandbox": "0.1.7-rc.2",
|
|
58
|
+
"@x1a0f3n9/dsh-sandbox-policy": "0.1.7-rc.2",
|
|
59
|
+
"@x1a0f3n9/dsh-session": "0.1.7-rc.2",
|
|
60
|
+
"@x1a0f3n9/dsh-system-prompt": "0.1.7-rc.2",
|
|
61
|
+
"@x1a0f3n9/dsh-tools": "0.1.7-rc.2",
|
|
62
|
+
"@x1a0f3n9/dsh-user-approval": "0.1.7-rc.2",
|
|
63
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
64
|
+
"@x1a0f3n9/dsh-session-projection": "0.1.7-rc.2",
|
|
65
|
+
"@x1a0f3n9/dsh-scope": "0.1.7-rc.2",
|
|
66
|
+
"@x1a0f3n9/dsh-ptc-runtime": "0.1.7-rc.2"
|
|
65
67
|
}
|
|
66
68
|
}
|