dsh-context-toolkit 0.1.0 → 0.2.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/README.md +9 -2
- package/README.zh.md +9 -2
- package/index.js +39 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,6 +36,12 @@ It separates *raw bytes* from *conclusions*: commands run in a child process, fi
|
|
|
36
36
|
|
|
37
37
|
## Install
|
|
38
38
|
|
|
39
|
+
From npm (recommended):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
dsh plugin --profile desktop add dsh-context-toolkit
|
|
43
|
+
```
|
|
44
|
+
|
|
39
45
|
From GitHub:
|
|
40
46
|
|
|
41
47
|
```bash
|
|
@@ -107,9 +113,10 @@ Tool switches: `tools.execute`, `tools.executeFile`, `tools.batchExecute`, `tool
|
|
|
107
113
|
The offline suites need no DSH runtime:
|
|
108
114
|
|
|
109
115
|
```bash
|
|
110
|
-
node smoke.mjs #
|
|
116
|
+
node smoke.mjs # 58 checks: contract, runtime discovery, tools, gate, knowledge base, observability, version reporting
|
|
111
117
|
node test-client.mjs # 27 checks: browser-half contract and bilingual dictionary parity
|
|
112
|
-
node test-package.mjs #
|
|
118
|
+
node test-package.mjs # 20 checks: publish manifest and the zero-dependency constraint
|
|
119
|
+
node release-check.mjs # 24 checks: release readiness (manifest, deps, tool count, gate, version, SHA coverage, no hardcoded paths)
|
|
113
120
|
```
|
|
114
121
|
|
|
115
122
|
## Known limits
|
package/README.zh.md
CHANGED
|
@@ -36,6 +36,12 @@
|
|
|
36
36
|
|
|
37
37
|
## 安装
|
|
38
38
|
|
|
39
|
+
从 npm 安装(推荐):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
dsh plugin --profile desktop add dsh-context-toolkit
|
|
43
|
+
```
|
|
44
|
+
|
|
39
45
|
从 GitHub 安装:
|
|
40
46
|
|
|
41
47
|
```bash
|
|
@@ -107,9 +113,10 @@ await ctk_search({ queries: ['rate limit', 'auth'] }); // 只取相关片段
|
|
|
107
113
|
离线套件不依赖 DSH 运行时:
|
|
108
114
|
|
|
109
115
|
```bash
|
|
110
|
-
node smoke.mjs #
|
|
116
|
+
node smoke.mjs # 58 项:契约、运行时探测、三工具、门禁、知识库、观测、版本自述
|
|
111
117
|
node test-client.mjs # 27 项:浏览器半体契约与双语字典一致性
|
|
112
|
-
node test-package.mjs #
|
|
118
|
+
node test-package.mjs # 20 项:发布清单与零依赖约束
|
|
119
|
+
node release-check.mjs # 24 项:发布就绪(清单/依赖/工具数/门禁/版本/SHA 覆盖/无硬编码路径)
|
|
113
120
|
```
|
|
114
121
|
|
|
115
122
|
## 已知边界
|
package/index.js
CHANGED
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
* no third-party runtime dependencies.
|
|
19
19
|
*/
|
|
20
20
|
import { homedir } from 'node:os'
|
|
21
|
-
import { existsSync, statSync, readdirSync } from 'node:fs'
|
|
22
|
-
import { join, isAbsolute, resolve, basename } from 'node:path'
|
|
21
|
+
import { existsSync, statSync, readdirSync, readFileSync } from 'node:fs'
|
|
22
|
+
import { join, isAbsolute, resolve, basename, dirname } from 'node:path'
|
|
23
|
+
import { fileURLToPath } from 'node:url'
|
|
23
24
|
import { runProcess, availableRuntimes, probeRuntimes, shellPlan, scratchDir } from './lib/runner.js'
|
|
24
25
|
import { mkdtempSync, rmSync } from 'node:fs'
|
|
25
26
|
import { openStore } from './lib/store.js'
|
|
@@ -27,6 +28,26 @@ import { openStore } from './lib/store.js'
|
|
|
27
28
|
export const name = 'dsh-context-toolkit'
|
|
28
29
|
export const inject = ['tools', 'systemPrompt']
|
|
29
30
|
|
|
31
|
+
/**
|
|
32
|
+
* The version this bundle actually ships, read from its own manifest.
|
|
33
|
+
*
|
|
34
|
+
* It used to be hardcoded and drifted: the manifest moved to 0.2.0 while the
|
|
35
|
+
* doctor still reported 0.1.0, so the one line meant to identify the build was
|
|
36
|
+
* the one line that could not be trusted. Reading the manifest keeps the two in
|
|
37
|
+
* step without a release step of its own.
|
|
38
|
+
*/
|
|
39
|
+
export const PLUGIN_VERSION = readManifestVersion()
|
|
40
|
+
|
|
41
|
+
/** Read the neighbouring package.json; a bundled copy still gets a usable value. */
|
|
42
|
+
export function readManifestVersion() {
|
|
43
|
+
try {
|
|
44
|
+
const here = dirname(fileURLToPath(import.meta.url))
|
|
45
|
+
const parsed = JSON.parse(readFileSync(join(here, 'package.json'), 'utf8'))
|
|
46
|
+
if (parsed && typeof parsed.version === 'string' && parsed.version) return parsed.version
|
|
47
|
+
} catch { /* not resolvable from here: still report something the doctor can print */ }
|
|
48
|
+
return '0.0.0'
|
|
49
|
+
}
|
|
50
|
+
|
|
30
51
|
const z = await loadSchemastery()
|
|
31
52
|
|
|
32
53
|
/**
|
|
@@ -262,9 +283,22 @@ export function apply(ctx, rawConfig) {
|
|
|
262
283
|
/** Names whose whole purpose is to pour raw bytes into the conversation. */
|
|
263
284
|
const FLOOD_TOOLS = new Set(['curl', 'wget', 'httpie', 'http', 'aria2c'])
|
|
264
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Every tool name that runs a shell command, so the gate can read its `command`.
|
|
288
|
+
*
|
|
289
|
+
* This list is the gate's blind spot if it drifts: a host name that is absent here
|
|
290
|
+
* is simply not inspected, and the flood tools run unchecked through it. `ops_bash`
|
|
291
|
+
* is the live example - dsh-ops publishes it (and does not publish `bash` at all),
|
|
292
|
+
* so before this list existed `curl` through `ops_bash` slipped past a gate that
|
|
293
|
+
* was refusing the identical command through `pwsh`.
|
|
294
|
+
*
|
|
295
|
+
* Add a name here when a shell tool appears; the other branches key off this set.
|
|
296
|
+
*/
|
|
297
|
+
const SHELL_TOOL_NAMES = new Set(['bash', 'pwsh', 'shell', 'ops_bash', 'bash_persistent', 'pwsh_persistent'])
|
|
298
|
+
|
|
265
299
|
function floodReason(toolName, args) {
|
|
266
300
|
const command = typeof args.command === 'string' ? args.command : ''
|
|
267
|
-
if (toolName
|
|
301
|
+
if (!SHELL_TOOL_NAMES.has(toolName)) return undefined
|
|
268
302
|
for (const word of FLOOD_TOOLS) {
|
|
269
303
|
if (new RegExp('(^|[ \\t;&|(])' + word + '([ \\t;&|)]|$)', 'i').test(command)) {
|
|
270
304
|
return 'dsh-context-toolkit: "' + word + '" pours whole responses into the transcript. '
|
|
@@ -312,7 +346,7 @@ function registerRoutingGate(ctx, config, stats) {
|
|
|
312
346
|
}
|
|
313
347
|
}
|
|
314
348
|
|
|
315
|
-
if ((toolName
|
|
349
|
+
if (SHELL_TOOL_NAMES.has(toolName) && config.bashNudgeMinCommandBytes > 0) {
|
|
316
350
|
const command = typeof args.command === 'string' ? args.command : ''
|
|
317
351
|
if (command.length > config.bashNudgeMinCommandBytes) {
|
|
318
352
|
const reason = 'dsh-context-toolkit: this command is about ' + command.length
|
|
@@ -1210,7 +1244,7 @@ function registerObservabilityTools(ctx, config, stats, store, storageDir, log)
|
|
|
1210
1244
|
|
|
1211
1245
|
// storage
|
|
1212
1246
|
ok('存储目录 Storage', storageDir)
|
|
1213
|
-
ok('版本 Version',
|
|
1247
|
+
ok('版本 Version', PLUGIN_VERSION)
|
|
1214
1248
|
|
|
1215
1249
|
lines.push('')
|
|
1216
1250
|
const failed = lines.filter((l) => l.startsWith('[FAIL]')).length
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context-toolkit",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "DeepSeek Harness bundle: native ctk_* sandbox tools, a routing gate that keeps bulk output out of the transcript, and a local full-text knowledge base. No third-party runtime dependencies.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|