@xiaoso/dsh-tool-plus 0.1.0-beta.2 → 0.1.0-beta.4
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.en.md +122 -0
- package/README.md +3 -2
- package/THIRD_PARTY_NOTICES.md +4 -35
- package/lib/abort-B7izMMna.mjs +51 -0
- package/lib/abort-D1_Z5Ut5.mjs +51 -0
- package/lib/abort-dIkZBV7Q.mjs +51 -0
- package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
- package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
- package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
- package/lib/anthropic-BWsZFzU8.mjs +262 -0
- package/lib/anthropic-CJCauvYz.mjs +3115 -0
- package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
- package/lib/anthropic-CZghe_9U.mjs +3115 -0
- package/lib/anthropic-sCMH7JID.mjs +262 -0
- package/lib/anthropic-tTntD8BD.mjs +262 -0
- package/lib/api-key-login-BzqNdM2y.mjs +157 -0
- package/lib/api-key-login-CWVwvHT1.mjs +157 -0
- package/lib/api-key-login-CpzSezsi.mjs +157 -0
- package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
- package/lib/aws-credentials-CXryMobh.mjs +867 -0
- package/lib/aws-credentials-ChG79ey-.mjs +867 -0
- package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
- package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
- package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
- package/lib/bun-shim.mjs +252 -12
- package/lib/bundled-references-CSuBco5p.mjs +55 -0
- package/lib/bundled-references-Cavaffah.mjs +55 -0
- package/lib/bundled-references-sLN0YdXU.mjs +55 -0
- package/lib/callback-server-BEFNf-jf.mjs +398 -0
- package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
- package/lib/callback-server-DDSrZ6l_.mjs +398 -0
- package/lib/client.js +111 -41
- package/lib/cursor-B3zg7EHj.mjs +273 -0
- package/lib/cursor-B6TUEmgP.mjs +135 -0
- package/lib/cursor-BIQfBC6V.mjs +135 -0
- package/lib/cursor-D8gvtTL3.mjs +135 -0
- package/lib/cursor-DNk6eXDd.mjs +5470 -0
- package/lib/cursor-DkSX2h3H.mjs +5441 -0
- package/lib/cursor-MjSm74IJ.mjs +273 -0
- package/lib/cursor-aJrXeYCb.mjs +273 -0
- package/lib/cursor-mJQwUKXK.mjs +5441 -0
- package/lib/device-code-DBo3B5nh.mjs +51 -0
- package/lib/device-code-DIb0FU-H.mjs +51 -0
- package/lib/device-code-OI_tQcmc.mjs +51 -0
- package/lib/devin-BHZZyMhO.mjs +95 -0
- package/lib/devin-BK7DHeca.mjs +114 -0
- package/lib/devin-CfMp3cXS.mjs +95 -0
- package/lib/devin-CldyPD8K.mjs +95 -0
- package/lib/devin-CzRpTUOA.mjs +114 -0
- package/lib/devin-D9zR5B_R.mjs +542 -0
- package/lib/devin-DXOeNyU7.mjs +542 -0
- package/lib/devin-Q1yem3lp.mjs +114 -0
- package/lib/devin-vNZTNUON.mjs +542 -0
- package/lib/error-B3bevhrs.mjs +1449 -0
- package/lib/error-Dd8DIqs-.mjs +1449 -0
- package/lib/error-yCSG0mGC.mjs +1449 -0
- package/lib/event-stream-BDPi64mK.mjs +151 -0
- package/lib/event-stream-BbFZJy-z.mjs +151 -0
- package/lib/event-stream-loUa0s1T.mjs +151 -0
- package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
- package/lib/github-copilot-4GaMtQmg.mjs +208 -0
- package/lib/github-copilot-B1yiyVRh.mjs +104 -0
- package/lib/github-copilot-B2HGSIJK.mjs +104 -0
- package/lib/github-copilot-BWT3eAOF.mjs +208 -0
- package/lib/github-copilot-CYkjeTi3.mjs +208 -0
- package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
- package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
- package/lib/gitlab-duo-akICyfeD.mjs +155 -0
- package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
- package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
- package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
- package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
- package/lib/google-BS4T25Pn.mjs +30 -0
- package/lib/google-TFe-7-of.mjs +30 -0
- package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
- package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
- package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
- package/lib/google-auth-B6gjsZvg.mjs +232 -0
- package/lib/google-auth-De7_s3eo.mjs +232 -0
- package/lib/google-auth-DhqpOYrX.mjs +232 -0
- package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
- package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
- package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
- package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
- package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
- package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
- package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
- package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
- package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
- package/lib/google-shared-CgKmmdO3.mjs +760 -0
- package/lib/google-shared-Dr-VG-ap.mjs +760 -0
- package/lib/google-shared-DzhCb9b0.mjs +760 -0
- package/lib/google-vertex-BDN2tLaD.mjs +99 -0
- package/lib/google-vertex-DopVOQOG.mjs +99 -0
- package/lib/google-vertex-kscbkyRb.mjs +99 -0
- package/lib/google-zyDOG9x7.mjs +30 -0
- package/lib/identity-Da1GPU9a.mjs +219 -0
- package/lib/identity-DnB63pS7.mjs +219 -0
- package/lib/identity-xRP7_eSR.mjs +219 -0
- package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
- package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
- package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
- package/lib/index.mjs +4608 -3935
- package/lib/kimi--wUOWER5.mjs +236 -0
- package/lib/kimi-DMVI-zrZ.mjs +236 -0
- package/lib/kimi-Dh0pv3WZ.mjs +236 -0
- package/lib/markit-BL3cH47U.mjs +1417 -0
- package/lib/markit-BNiNY6SE.mjs +1417 -0
- package/lib/markit-M0jhziqU.mjs +1417 -0
- package/lib/minimax-code-BK-3eBbz.mjs +53 -0
- package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
- package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
- package/lib/models-CfT4coYT.mjs +104660 -0
- package/lib/models-D_XnT6ay.mjs +104660 -0
- package/lib/models-SGASygJ3.mjs +104660 -0
- package/lib/ollama-BQMGPxtV.mjs +589 -0
- package/lib/ollama-DPzBmq89.mjs +589 -0
- package/lib/ollama-DoBz5SFm.mjs +589 -0
- package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
- package/lib/openai-codex-CQL_kvYL.mjs +255 -0
- package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
- package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
- package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
- package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
- package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
- package/lib/openai-completions-DIf361kF.mjs +1360 -0
- package/lib/openai-completions-i8doczAk.mjs +1360 -0
- package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
- package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
- package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
- package/lib/openai-responses-BqXJInHX.mjs +867 -0
- package/lib/openai-responses-DTkBiiy-.mjs +867 -0
- package/lib/openai-responses-Db_a-U4-.mjs +867 -0
- package/lib/opencode-DaJjcUbf.mjs +38 -0
- package/lib/opencode-DhMolSoB.mjs +38 -0
- package/lib/opencode-Rq_Q2vAO.mjs +38 -0
- package/lib/perplexity-9b-RQ0mV.mjs +194 -0
- package/lib/perplexity-C4iLVMUj.mjs +194 -0
- package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
- package/lib/proxy-DDqrmjjC.mjs +190 -0
- package/lib/proxy-ZtUcl6r5.mjs +190 -0
- package/lib/proxy-pM_NIv-H.mjs +190 -0
- package/lib/request-debug-HJMoJncL.mjs +183 -0
- package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
- package/lib/scrapers-BkFfcPHj.mjs +9198 -0
- package/lib/scrapers-CL-WgdU1.mjs +9198 -0
- package/lib/scrapers-CVptboMs.mjs +9198 -0
- package/lib/scrapers-CipyKyCH.mjs +9198 -0
- package/lib/scrapers-DGfrYhtw.mjs +9198 -0
- package/lib/scrapers-DSUPYoUF.mjs +9198 -0
- package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
- package/lib/scrapers-nhQAvc8d.mjs +9198 -0
- package/lib/shell-snapshot-fn-env.sh +67 -43
- package/lib/src-BgpusnsB.mjs +5076 -0
- package/lib/src-DTid0g4K.mjs +5001 -0
- package/lib/src-lDmkSRbm.mjs +5006 -0
- package/lib/stream-BlldLkVq.mjs +10236 -0
- package/lib/stream-CRtexYLe.mjs +10236 -0
- package/lib/stream-C_RAoxJC.mjs +10236 -0
- package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
- package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
- package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
- package/lib/turndown-DN7ByzEI.mjs +667 -0
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/config/fields.d.ts +1 -1
- package/lib/types/config/settings.d.ts +25 -3
- package/lib/types/config/truncate.d.ts +9 -5
- package/lib/types/tools/bash/background.d.ts +1 -1
- package/lib/types/tools/bash/bash-executor.d.ts +4 -0
- package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
- package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
- package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
- package/lib/types/tools/bash/render.d.ts +4 -3
- package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
- package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
- package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
- package/lib/types/tools/bash/streaming-output.d.ts +12 -212
- package/lib/types/tools/bash/which.d.ts +20 -0
- package/lib/types/tools/bash/windows-shell.d.ts +31 -0
- package/lib/types/tools/edit/adapter/index.d.ts +25 -3
- package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
- package/lib/types/tools/glob/adapter/index.d.ts +27 -1
- package/lib/types/tools/grep/adapter/index.d.ts +29 -1
- package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
- package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
- package/lib/types/tools/omp/sdk.d.ts +6 -0
- package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
- package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
- package/lib/types/tools/omp/tools/read.d.ts +2 -8
- package/lib/types/tools/omp/tools/write.d.ts +4 -4
- package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
- package/lib/types/tools/read/adapter/index.d.ts +4 -1
- package/lib/types/tools/read-image/index.d.ts +4 -0
- package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
- package/lib/types/tools/shared/bun-shim.d.ts +39 -3
- package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
- package/lib/types/tools/shared/image-bridge.d.ts +98 -0
- package/lib/types/tools/shared/omp-prompt.d.ts +17 -9
- package/lib/types/tools/shared/session-state.d.ts +9 -3
- package/lib/utils-2Wq2eATG.mjs +8119 -0
- package/lib/utils-BnX8O3vi.mjs +12303 -0
- package/lib/utils-Bw139LTz.mjs +8119 -0
- package/lib/utils-CE8N8P4Q.mjs +12315 -0
- package/lib/utils-CZw4tVZQ.mjs +12315 -0
- package/lib/utils-C_MrQ_0z.mjs +12301 -0
- package/lib/utils-CiGN7OHR.mjs +12315 -0
- package/lib/utils-Cp76gCyk.mjs +8119 -0
- package/lib/utils-D0GRDgAr.mjs +12315 -0
- package/lib/utils-D0Z1fyoO.mjs +12299 -0
- package/lib/utils-D2YknRk4.mjs +51 -0
- package/lib/utils-DppGHXQB.mjs +51 -0
- package/lib/utils-DzXZDfYc.mjs +51 -0
- package/lib/utils-W8WdSBpX.mjs +12315 -0
- package/lib/vision-guard-01qSwFpf.mjs +92 -0
- package/lib/vision-guard-BDD4OrKo.mjs +92 -0
- package/lib/vision-guard-DzZGaOga.mjs +92 -0
- package/lib/wafer-CgtPHerf.mjs +17 -0
- package/lib/wafer-DRU0EjZX.mjs +17 -0
- package/lib/wafer-cBtrn6q9.mjs +17 -0
- package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
- package/lib/xai-oauth-CMal8l1O.mjs +446 -0
- package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
- package/lib/xiaomi-CZgwvX2G.mjs +157 -0
- package/lib/xiaomi-D2qT5cAC.mjs +157 -0
- package/lib/xiaomi-Dd87KSg5.mjs +157 -0
- package/lib/zai-7DWMkEqM.mjs +203 -0
- package/lib/zai-C59YnomG.mjs +203 -0
- package/lib/zai-CFeOt-53.mjs +203 -0
- package/lib/zip-Cg9ANN_U.mjs +1316 -0
- package/lib/zip-D36ZKsP8.mjs +1316 -0
- package/lib/zip-D6QXpvaJ.mjs +1316 -0
- package/package.json +14 -10
- package/presets/package.json +1 -1
- package/presets/tool-plus-ptc/preset.yml +1 -1
- package/presets/tool-plus-standard/preset.yml +1 -1
package/README.en.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# dsh-tool-plus — Essential Tools Enhancement for DeepSeek Harness
|
|
2
|
+
|
|
3
|
+
[简体中文](./README.md) | English
|
|
4
|
+
|
|
5
|
+
Essential tools enhancement for DeepSeek Harness: persistent bash, structured read, multi-mode edit, atomic write, full-text search, and direct image reading — one plugin covers it all. Ported from the [Oh My Pi](https://github.com/can1357/oh-my-pi) core; once installed it automatically takes over the official bash / pwsh / file / search tools, with optional `ast_grep` / `ast_edit` structural search and rewrite.
|
|
6
|
+
|
|
7
|
+
> Currently in early beta — behavior and configuration may change at any time.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **bash**: persistent shell; `cd` and `export` keep state across calls; verbose logs (git/npm/cargo…) are condensed automatically; overlong output keeps only head and tail, with the full content written to disk for later retrieval; long-running commands are moved to the background automatically; optionally intercepts `cat`, `grep`, `find`, and `sed -i` to steer you toward the dedicated tools
|
|
12
|
+
- **read**: precise line-range reading (supports `:N-M`, `:raw`, and multiple ranges); large code files return a structural summary by default, with details expanded on demand; zip/tar archives, SQLite, notebooks, and PDFs read directly; PNG / JPEG / WebP / GIF images read directly, oversized ones scaled down automatically; can fetch web content (including images embedded in the page)
|
|
13
|
+
- **write**: atomic writes that return a diff of the changes; supports patch-style writing, and can write directly into zip/tar archive members and SQLite data
|
|
14
|
+
- **edit**: `replace` by default, with patch / hashline / apply-patch formats also supported; multi-hunk edits, uniqueness validation, fuzzy matching tolerant of whitespace differences
|
|
15
|
+
- **grep / glob**: full-text search and filename matching; mtime sorting, context lines, and configurable ignore rules
|
|
16
|
+
- **ast_grep / ast_edit** (optional): syntax-tree based structural code search and rewrite, enabled in settings
|
|
17
|
+
- **agent presets**: two companion templates — Standard enhanced and PTC (Code Mode) — installable in one command (see Installation)
|
|
18
|
+
|
|
19
|
+
## Recommended Environment & Configuration
|
|
20
|
+
|
|
21
|
+
- **Full-access mode**: the plugin is best used under `danger-full-access`, which avoids file writes being blocked by mistake in sandboxed modes.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
Install **both** the plugin and the presets:
|
|
26
|
+
|
|
27
|
+
- **Tool plugin**: provides the full toolset and takes over the official bash / pwsh / file / search tools;
|
|
28
|
+
- **Agent presets**: the official presets contain no configuration for these tools, so the stock setup is missing capabilities — the Standard / PTC templates exist to fill exactly that gap.
|
|
29
|
+
|
|
30
|
+
### Install from npm (recommended)
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
dsh plugin --profile web add @xiaoso/dsh-tool-plus@beta
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Install from GitHub
|
|
37
|
+
|
|
38
|
+
Track the latest development build (the project has no formal release yet — every install is a test build):
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
dsh plugin --profile web add github:xiaoso456/dsh-tool-plus
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Local development
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
dsh plugin --profile web add link:<path to this repo>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Preset installation
|
|
51
|
+
|
|
52
|
+
**Option 1 · Install with the npx script**
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npx @xiaoso/dsh-tool-plus-presets@beta
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Option 2 · Have an AI session configure the presets** (no dependency on the package above) — paste the following into an AI session that can edit files on your machine:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
Please install the two enhanced agent presets for DeepSeek Harness.
|
|
62
|
+
|
|
63
|
+
1. Locate the official preset directory config/agent-presets/ inside the globally installed dsh package;
|
|
64
|
+
it contains the standard and code templates, each with preset.yml and agent.cordis.yml.
|
|
65
|
+
(On Windows it is under the global node_modules\@deepseek-ai\dsh\ directory; on macOS/Linux run
|
|
66
|
+
npm root -g first to locate it; if you cannot find it, search the whole disk for the installed
|
|
67
|
+
@deepseek-ai/dsh package.)
|
|
68
|
+
2. Create two directories under ~/.dsh/.agent-presets/: tool-plus-standard and tool-plus-ptc.
|
|
69
|
+
|
|
70
|
+
3. tool-plus-standard: copy over the two files from the official standard template, then modify:
|
|
71
|
+
- Replace preset.yml entirely with:
|
|
72
|
+
name: Tool Plus 标准增强版
|
|
73
|
+
description: Full standard-mode capabilities, file/shell toolset replaced by @xiaoso/dsh-tool-plus, pwsh disabled by default
|
|
74
|
+
order: 2
|
|
75
|
+
- agent.cordis.yml:
|
|
76
|
+
a. Change the entry with id: tool-bash to
|
|
77
|
+
- id: tool-plus
|
|
78
|
+
name: '@xiaoso/dsh-tool-plus'
|
|
79
|
+
disabled: true
|
|
80
|
+
b. Change the id: tool-pwsh entry's platform-conditional disable into a plain disabled: true line
|
|
81
|
+
c. Delete the two entries with id: tool-fs and id: tool-fs-search entirely
|
|
82
|
+
(the latter also carries a sampleOverCapGlobResults setting)
|
|
83
|
+
|
|
84
|
+
4. tool-plus-ptc: copy over the two files from the official code template and make exactly the same
|
|
85
|
+
three changes as in step 3, except replace preset.yml with:
|
|
86
|
+
name: Tool Plus PTC 增强版
|
|
87
|
+
description: Full PTC (Code Mode) capabilities, file/shell toolset replaced by @xiaoso/dsh-tool-plus, pwsh disabled by default
|
|
88
|
+
order: 3
|
|
89
|
+
|
|
90
|
+
5. When done, list the file trees of both directories and remind me to restart any running dsh
|
|
91
|
+
so the presets take effect.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Keep the `name:` fields as shown — they match the templates the npx script installs. Both options produce the same result: the files land in `~/.dsh/.agent-presets/`; restart dsh and select the preset in your session to activate it.
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
Works out of the box, no configuration needed. Common tweaks: background threshold (`autoBackgroundMs`), timeouts (`defaultTimeoutMs` / `maxTimeoutMs`), the output truncation window, the default edit mode (`editMode`, default `replace`), and the structured summary toggle (`readSummarizeEnabled`).
|
|
99
|
+
|
|
100
|
+
## Requirements
|
|
101
|
+
|
|
102
|
+
- **dsh CLI**: installed globally, `npm i -g @deepseek-ai/dsh`
|
|
103
|
+
- **Node.js** ≥ 22.19 or ≥ 24
|
|
104
|
+
- **Git Bash** (recommended): serves as the bash execution environment on Windows
|
|
105
|
+
- Targets DeepSeek Harness `dsh` v0.1.1-rc.2 (pre-release; interfaces may change)
|
|
106
|
+
|
|
107
|
+
## Notes
|
|
108
|
+
|
|
109
|
+
- No standalone `pwsh` tool: shell work is handled by the more capable persistent `bash`
|
|
110
|
+
|
|
111
|
+
## Build
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
pnpm install
|
|
115
|
+
pnpm build # type declarations (tsc) + tsdown bundle + asset copy
|
|
116
|
+
pnpm typecheck
|
|
117
|
+
pnpm test # includes real-bash cases; needs Git Bash on Windows, auto-skips when missing
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
[MIT](LICENSE); third-party component licenses in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# dsh-tool-plus — DeepSeek Harness 基础工具增强
|
|
2
2
|
|
|
3
|
+
简体中文 | [English](./README.en.md)
|
|
4
|
+
|
|
3
5
|
DeepSeek Harness 基础工具增强:持久 bash、结构化 read、多模式 edit、原子 write、全文搜索、图像直读,一个插件全覆盖。基于 [Oh My Pi](https://github.com/can1357/oh-my-pi) 内核移植,安装后自动接管官方 bash / pwsh / 文件 / 搜索工具,另有可选的 `ast_grep` / `ast_edit` 结构化搜索与重写。
|
|
4
6
|
|
|
5
7
|
> 当前为早期测试版(beta),行为与配置可能随时调整。
|
|
@@ -7,11 +9,10 @@ DeepSeek Harness 基础工具增强:持久 bash、结构化 read、多模式 e
|
|
|
7
9
|
## 功能特性
|
|
8
10
|
|
|
9
11
|
- **bash**:持久 shell,`cd`、`export` 跨调用保持状态;冗长日志(git/npm/cargo…)自动压缩;超长输出只保留头尾,完整内容落盘可回读;长命令自动转后台;可选拦截 `cat`、`grep`、`find`、`sed -i`,引导改用专用工具
|
|
10
|
-
- **read**:按行区间精准读取(支持 `:N-M`、`:raw`、多区间);大代码文件默认返回结构摘要,细节按需展开;zip/tar 归档、SQLite、notebook、PDF
|
|
12
|
+
- **read**:按行区间精准读取(支持 `:N-M`、`:raw`、多区间);大代码文件默认返回结构摘要,细节按需展开;zip/tar 归档、SQLite、notebook、PDF 直接读;PNG / JPEG / WebP / GIF 图片直读,超大图自动缩放;可抓取网页内容(含网页内图片)
|
|
11
13
|
- **write**:原子写入,返回修改 diff;支持补丁式写入,可直接写 zip/tar 归档成员与 SQLite 数据
|
|
12
14
|
- **edit**:replace 默认,另支持 patch / hashline / apply-patch 三种补丁格式;多段编辑、唯一性校验、空白差异模糊匹配
|
|
13
15
|
- **grep / glob**:全文搜索与文件名匹配;mtime 排序、上下文行、忽略规则可配置
|
|
14
|
-
- **read_image**:直读 PNG / JPEG / WebP / GIF,超大图自动缩放。*备注:图像读取不在本插件的初始规划内——官方工具套件把多个工具捆绑在同一插件里,为保证完整体验而一并移植。*
|
|
15
16
|
- **ast_grep / ast_edit**(可选):基于语法树的结构化代码搜索与重写,可在设置中开启
|
|
16
17
|
- **agent 预设**:标准增强版 / PTC(Code Mode)两套配套模板,一条命令安装(见安装章节)
|
|
17
18
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
# Third-Party Notices
|
|
2
2
|
|
|
3
|
-
This project contains code adapted from
|
|
4
|
-
[oh-my-pi](https://github.com/can1357/oh-my-pi)
|
|
5
|
-
Harness tool packages ([@deepseek-ai/dsh-tool-fs](https://www.npmjs.com/package/@deepseek-ai/dsh-tool-fs)).
|
|
3
|
+
This project contains code adapted from the upstream project
|
|
4
|
+
[oh-my-pi](https://github.com/can1357/oh-my-pi).
|
|
6
5
|
|
|
7
6
|
Scope of ported upstream code:
|
|
8
7
|
|
|
9
|
-
- from **oh-my-pi** (MIT,
|
|
8
|
+
- from **oh-my-pi** (MIT, notice below): the tool suite sources under
|
|
10
9
|
`src/tools/` (bash runtime, read, write, edit, grep, glob, plus the OMP
|
|
11
10
|
`omp/` engine sources they wrap), and the hashline patch engine fused
|
|
12
11
|
in-repo at `src/tools/hashline/engine/` (upstream `packages/hashline`,
|
|
13
|
-
with small Node-runtime adaptations)
|
|
14
|
-
- from **`@deepseek-ai/dsh-tool-fs`** (MIT, second notice below): the
|
|
15
|
-
`read_image` image tool at `src/tools/read-image/`, ported from the
|
|
16
|
-
official read-image implementation to keep the tool surface identical.
|
|
12
|
+
with small Node-runtime adaptations).
|
|
17
13
|
|
|
18
14
|
---
|
|
19
15
|
|
|
@@ -44,30 +40,3 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
44
40
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
45
41
|
SOFTWARE.
|
|
46
42
|
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
@deepseek-ai/dsh-tool-fs (read_image portion) - MIT
|
|
50
|
-
|
|
51
|
-
-- License
|
|
52
|
-
|
|
53
|
-
(The MIT License)
|
|
54
|
-
|
|
55
|
-
Copyright (c) 2026 DeepSeek
|
|
56
|
-
|
|
57
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
58
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
59
|
-
in the Software without restriction, including without limitation the rights
|
|
60
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
61
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
62
|
-
furnished to do so, subject to the following conditions:
|
|
63
|
-
|
|
64
|
-
The above copyright notice and this permission notice shall be included in all
|
|
65
|
-
copies or substantial portions of the Software.
|
|
66
|
-
|
|
67
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
68
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
69
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
70
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
71
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
72
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
73
|
-
SOFTWARE.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { v as AbortError } from "./error-B3bevhrs.mjs";
|
|
4
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/utils/abort.ts
|
|
5
|
+
/**
|
|
6
|
+
* Tracks whether a merged request signal was aborted by the caller or by provider-local logic.
|
|
7
|
+
*
|
|
8
|
+
* Caller aborts always take priority. When both the caller and a local watchdog fire near
|
|
9
|
+
* each other, the merged `requestSignal.reason` reflects whichever AbortController called
|
|
10
|
+
* `.abort()` first — but ordering is racy and not meaningful for upstream consumers. What
|
|
11
|
+
* matters is intent: if the caller's signal aborted, the request was cancelled by the
|
|
12
|
+
* caller, and any local watchdog reason is incidental and **MUST NOT** be surfaced as a
|
|
13
|
+
* retryable transient error (which would cause auto-retry to re-enter streaming and leave
|
|
14
|
+
* the UI showing a spinner the user already tried to cancel).
|
|
15
|
+
*/
|
|
16
|
+
function createAbortSourceTracker(callerSignal) {
|
|
17
|
+
const requestAbortController = new AbortController();
|
|
18
|
+
const requestSignal = callerSignal ? AbortSignal.any([callerSignal, requestAbortController.signal]) : requestAbortController.signal;
|
|
19
|
+
let localAbortReason;
|
|
20
|
+
return {
|
|
21
|
+
requestAbortController,
|
|
22
|
+
requestSignal,
|
|
23
|
+
abortLocally(reason) {
|
|
24
|
+
localAbortReason = reason;
|
|
25
|
+
requestAbortController.abort(reason);
|
|
26
|
+
return reason;
|
|
27
|
+
},
|
|
28
|
+
getLocalAbortReason() {
|
|
29
|
+
if (!localAbortReason || callerSignal?.aborted) return void 0;
|
|
30
|
+
return requestSignal.reason === localAbortReason ? localAbortReason : void 0;
|
|
31
|
+
},
|
|
32
|
+
wasCallerAbort() {
|
|
33
|
+
return callerSignal?.aborted === true;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Race a shared promise against a caller's AbortSignal without coupling the
|
|
39
|
+
* underlying work to that signal. The shared promise keeps running (and caches
|
|
40
|
+
* its result) even when an individual caller bails out.
|
|
41
|
+
*/
|
|
42
|
+
function raceWithSignal(promise, signal) {
|
|
43
|
+
if (!signal) return promise;
|
|
44
|
+
if (signal.aborted) return Promise.reject(signal.reason ?? new AbortError());
|
|
45
|
+
const { promise: aborted, reject } = Promise.withResolvers();
|
|
46
|
+
const onAbort = () => reject(signal.reason ?? new AbortError());
|
|
47
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
48
|
+
return Promise.race([promise, aborted]).finally(() => signal.removeEventListener("abort", onAbort));
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { raceWithSignal as n, createAbortSourceTracker as t };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { v as AbortError } from "./error-yCSG0mGC.mjs";
|
|
4
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/utils/abort.ts
|
|
5
|
+
/**
|
|
6
|
+
* Tracks whether a merged request signal was aborted by the caller or by provider-local logic.
|
|
7
|
+
*
|
|
8
|
+
* Caller aborts always take priority. When both the caller and a local watchdog fire near
|
|
9
|
+
* each other, the merged `requestSignal.reason` reflects whichever AbortController called
|
|
10
|
+
* `.abort()` first — but ordering is racy and not meaningful for upstream consumers. What
|
|
11
|
+
* matters is intent: if the caller's signal aborted, the request was cancelled by the
|
|
12
|
+
* caller, and any local watchdog reason is incidental and **MUST NOT** be surfaced as a
|
|
13
|
+
* retryable transient error (which would cause auto-retry to re-enter streaming and leave
|
|
14
|
+
* the UI showing a spinner the user already tried to cancel).
|
|
15
|
+
*/
|
|
16
|
+
function createAbortSourceTracker(callerSignal) {
|
|
17
|
+
const requestAbortController = new AbortController();
|
|
18
|
+
const requestSignal = callerSignal ? AbortSignal.any([callerSignal, requestAbortController.signal]) : requestAbortController.signal;
|
|
19
|
+
let localAbortReason;
|
|
20
|
+
return {
|
|
21
|
+
requestAbortController,
|
|
22
|
+
requestSignal,
|
|
23
|
+
abortLocally(reason) {
|
|
24
|
+
localAbortReason = reason;
|
|
25
|
+
requestAbortController.abort(reason);
|
|
26
|
+
return reason;
|
|
27
|
+
},
|
|
28
|
+
getLocalAbortReason() {
|
|
29
|
+
if (!localAbortReason || callerSignal?.aborted) return void 0;
|
|
30
|
+
return requestSignal.reason === localAbortReason ? localAbortReason : void 0;
|
|
31
|
+
},
|
|
32
|
+
wasCallerAbort() {
|
|
33
|
+
return callerSignal?.aborted === true;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Race a shared promise against a caller's AbortSignal without coupling the
|
|
39
|
+
* underlying work to that signal. The shared promise keeps running (and caches
|
|
40
|
+
* its result) even when an individual caller bails out.
|
|
41
|
+
*/
|
|
42
|
+
function raceWithSignal(promise, signal) {
|
|
43
|
+
if (!signal) return promise;
|
|
44
|
+
if (signal.aborted) return Promise.reject(signal.reason ?? new AbortError());
|
|
45
|
+
const { promise: aborted, reject } = Promise.withResolvers();
|
|
46
|
+
const onAbort = () => reject(signal.reason ?? new AbortError());
|
|
47
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
48
|
+
return Promise.race([promise, aborted]).finally(() => signal.removeEventListener("abort", onAbort));
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { raceWithSignal as n, createAbortSourceTracker as t };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { v as AbortError } from "./error-Dd8DIqs-.mjs";
|
|
4
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/utils/abort.ts
|
|
5
|
+
/**
|
|
6
|
+
* Tracks whether a merged request signal was aborted by the caller or by provider-local logic.
|
|
7
|
+
*
|
|
8
|
+
* Caller aborts always take priority. When both the caller and a local watchdog fire near
|
|
9
|
+
* each other, the merged `requestSignal.reason` reflects whichever AbortController called
|
|
10
|
+
* `.abort()` first — but ordering is racy and not meaningful for upstream consumers. What
|
|
11
|
+
* matters is intent: if the caller's signal aborted, the request was cancelled by the
|
|
12
|
+
* caller, and any local watchdog reason is incidental and **MUST NOT** be surfaced as a
|
|
13
|
+
* retryable transient error (which would cause auto-retry to re-enter streaming and leave
|
|
14
|
+
* the UI showing a spinner the user already tried to cancel).
|
|
15
|
+
*/
|
|
16
|
+
function createAbortSourceTracker(callerSignal) {
|
|
17
|
+
const requestAbortController = new AbortController();
|
|
18
|
+
const requestSignal = callerSignal ? AbortSignal.any([callerSignal, requestAbortController.signal]) : requestAbortController.signal;
|
|
19
|
+
let localAbortReason;
|
|
20
|
+
return {
|
|
21
|
+
requestAbortController,
|
|
22
|
+
requestSignal,
|
|
23
|
+
abortLocally(reason) {
|
|
24
|
+
localAbortReason = reason;
|
|
25
|
+
requestAbortController.abort(reason);
|
|
26
|
+
return reason;
|
|
27
|
+
},
|
|
28
|
+
getLocalAbortReason() {
|
|
29
|
+
if (!localAbortReason || callerSignal?.aborted) return void 0;
|
|
30
|
+
return requestSignal.reason === localAbortReason ? localAbortReason : void 0;
|
|
31
|
+
},
|
|
32
|
+
wasCallerAbort() {
|
|
33
|
+
return callerSignal?.aborted === true;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Race a shared promise against a caller's AbortSignal without coupling the
|
|
39
|
+
* underlying work to that signal. The shared promise keeps running (and caches
|
|
40
|
+
* its result) even when an individual caller bails out.
|
|
41
|
+
*/
|
|
42
|
+
function raceWithSignal(promise, signal) {
|
|
43
|
+
if (!signal) return promise;
|
|
44
|
+
if (signal.aborted) return Promise.reject(signal.reason ?? new AbortError());
|
|
45
|
+
const { promise: aborted, reject } = Promise.withResolvers();
|
|
46
|
+
const onAbort = () => reject(signal.reason ?? new AbortError());
|
|
47
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
48
|
+
return Promise.race([promise, aborted]).finally(() => signal.removeEventListener("abort", onAbort));
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { raceWithSignal as n, createAbortSourceTracker as t };
|