Bundle
dsh-coding-tools
Bounded code reading, exact-version editing, structural search, and LSP intelligence for DeepSeek Harness.
- Source
- leonardoxr
- License
- MIT
- Updated
- Updated 6 days ago
Readme
# dsh-coding-tools
English | [简体中文](README.zh.md)
A [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/en/develop/basic/) host plugin with a narrowly scoped Settings card that adds compact, bounded coding tools without modifying DSH:
- `code_read` — UTF-8 code windows with exact-byte version tokens
- `edit_ranges` — atomic, observed-range edits with operator-configurable approval
- `ast_grep` — pinned ast-grep CLI over one provider-read file snapshot, with pagination and read-only process confinement
- `lsp` — persistent read-only language-server queries with bounded JSON-RPC
- Fresh diagnostic summaries after plugin-owned edits when the matching LSP server is already active
`ast_edit` and DAP debugging are deliberately **not registered** in the secure initial release. The browser bundle is limited to the Coding tools Settings card.
## Requirements
- Node.js 22.19+ or 24+
- DeepSeek Harness 0.1.1-rc.2 or compatible public service contracts
- A DSH profile that supplies `tools`, `fs`, `sandboxPolicy`, `sandbox`, `approval`, `spillStore`, `subprocess`, and `settings` (the stock Web profile does)
- Optional absolute-path language server executables configured by the profile operator
## Install
Build a local checkout, then enroll it in a DSH profile with the supported profile command:
```powershell
pnpm install
pnpm check
dsh plugin --profile web add "C:\absolute\path\to\dsh-coding-tools"
```
The package contributes [`cordis.patch.yml`](cordis.patch.yml), which inserts the package-prefixed row `dsh-coding-tools`. Restart the Web profile after host plugin changes. A raw source patch alone is not package enrollment.
For a published or Git install, pin a release or commit instead of a floating branch.
## Configuration
An expandable **Coding tools** card appears in **Settings → Plugins → Plugin configuration**. It provides switches for `code_read`, `edit_ranges`, `ast_grep`, and `lsp`, separate **Require edit approval** and **Require process-start approval** controls, and a conspicuously warned native-Windows compatibility opt-in for reduced process isolation. Approval prompts default on. Advanced limits and language-server plans remain profile configuration. Saved settings persist in DSH's user layer and apply live: disabled tools are unregistered, enabled tools are registered, and process-backed resources are stopped or recreated without restarting DSH Web. Reconfiguration cancels in-flight reads and queries, drains edits that may already have committed, and invalidates existing cursors and `code_read` version tokens.
Profile patch layers can replace the inserted row with explicit base configuration:
```yaml
- insert:
- id: dsh-coding-tools
name: 'dsh-coding-tools'
config:
inlineMaxBytes: 8192
approvals:
editRanges: true
processStart: true
processPolicy:
allowWindowsPartialReadOnlyProcessConfinement: false
codeRead:
enabled: true
defaultLines: 200
maxLines: 2000
maxBytes: 262144
maxFileBytes: 16777216
snapshotMaxBytes: 67108864
versionedEdit:
enabled: true
requireObservedRanges: true
maxOperations: 100
maxChangedBytes: 1048576
diagnosticsOnWrite: true
ast:
grepEnabled: true
executable: '' # empty = pinned @ast-grep/cli binary
maxFileBytes: 2097152
maxMatchesPerPage: 50
maxTotalMatches: 5000
timeoutMs: 30000
lsp:
enabled: true
servers:
clangd:
command: '/absolute/path/to/clangd'
args: ['--background-index=false']
extensions: ['.c', '.cc', '.cpp', '.h', '.hpp']
languageId: 'cpp'
env: {}
maxOpenDocuments: 64
maxDocumentBytes: 16777216
maxDiagnosticBytes: 4194304
debug:
enabled: false
```
Executable paths in configuration must be absolute. Repository files never select a binary or inject command-line arguments. Environment entries are explicit; DSH's subprocess provider removes ambient credential-shaped and `DSH_*` variables before applying them.
See [Configuration reference](docs/CONFIGURATION.md).
### Native Windows compatibility
`processPolicy.allowWindowsPartialReadOnlyProcessConfinement` defaults to `false`. When explicitly enabled on native Windows, only `ast_grep` and configured LSP starts may accept DSH's `partial` restricted-token enforcement; `full` remains required on every other host and for every unknown enforcement value. The process policy is still forced to `read-only`, executable plans remain operator-controlled, and all normal bounds and lifecycle cleanup remain active.
This is reduced isolation, not an equivalent Windows implementation of Linux full confinement. Everyone-writable ACLs and NTFS hard links can weaken write isolation, FAT-class targets outside granted roots remain writable, and the backend does not isolate reads, network access, or process visibility. Use it only with trusted repositories and executables.
## Tool workflow
### Exact reads and edits
1. Call `code_read` with `file`, and optional one-indexed `offset` / `limit`.
2. Retain the returned `version`.
3. Call `edit_ranges` with that exact `file`, `version`, and non-overlapping operations.
4. Under a read-only session, retry the denied call once with `sandbox_permissions: workspace-write` and a sentence in `justification`; sandbox escalation always requires its own one-call approval. Under an already-writable session, the ordinary mutation prompt is required only when `approvals.editRanges` is enabled.
Disabling ordinary edit approval does not widen sandbox policy. The standard DSH escalation fields do, for one call only, and always retain approval; they are advertised only when the mounted filesystem reports sandbox enforcement. A bare filesystem cannot escalate and fails closed under read-only policy. Source-changing operations must refer only to complete lines present in the canonical byte-bounded `code_read` result for the same owner, canonical target, and exact version. Oversized lines may be reported with an explicitly unobserved preview and continuation offset, but are never authorized for mutation. Because the public host observation event is whole-target rather than range-aware, the plugin publishes it only after accumulated same-version `code_read` pages visibly cover the complete file; paginate to complete coverage before editing. `append` is the sole observed-range exception, but still requires an observed version. All operations validate before one provider-version-guarded atomic write.
Line operation semantics:
- `replace`: replace inclusive whole lines and preserve the following line separator
- `delete`: remove inclusive whole lines
- `insert_before` / `insert_after`: insert line-shaped text using the file's dominant separator
- `append`: append text, adding one dominant separator when the file lacks a final separator
BOM, existing untouched line endings, and UTF-8 bytes are preserved. Invalid UTF-8 and NUL-bearing binary files fail closed. Complete-file read limits are separate from returned-result limits. Successful publication always returns `applied: true`; `intendedVersion` is always identified, while `newVersion` is present only after a verified landed read. `landedExact` and `postWriteWarning` make any post-commit verification or diagnostic problem explicit so callers do not retry a committed write blindly. Diff previews and the complete structured result are UTF-8-byte bounded, with explicit sizes, truncation reasons, and a spill locator when available.
### Structural search
`ast_grep` accepts a pattern, exactly one regular workspace file in `paths`, a required language, optional strictness, a page limit, and an owner-scoped cursor. Before launch it:
- resolves the file through `ctx.fs` and proves canonical workspace containment
- rejects explicit symlinks and directories
- performs a stable, byte-bounded provider read
- passes that immutable snapshot to ast-grep over stdin, never as a process path
- enforces result, capture, cursor, output, and time caps
- asks once for that process launch when `approvals.processStart` is enabled and forces read-only DSH policy; full enforcement remains mandatory unless a trusted operator explicitly enables the native-Windows partial-confinement fallback
Broad directory scans are deliberately gated off. DSH does not currently expose an atomic process read-whitelist/open-handle contract, so passing workspace paths to a later process would leave a read-side TOCTOU race. Completed records retained from lossy bounded output may still be returned safely. Matches and parse errors are deduplicated, deterministically sorted, capped, and paged by both item count and rendered/structured UTF-8 bytes. Incomplete coverage is reported with explicit counts, byte ceilings, `limitReasons`, and bounded `parseErrors`.
### Language servers
`lsp` supports `hover`, `definition`, `references`, `symbols`, and `diagnostics`. A configured server starts lazily, requesting one-shot approval when `approvals.processStart` is enabled, remains scoped to owner + canonical workspace + profile, and stops on idle timeout or plugin disposal.
The client advertises no edit or command capability. Server requests for `workspace/applyEdit` are explicitly rejected; dynamic capabilities, terminal launch, workspace commands, and unknown server requests never execute. Results outside the session workspace are discarded.
Every file-backed action synchronizes the complete stable UTF-8 document under `lsp.maxDocumentBytes`; a source prefix is never presented as a complete document. LSP source limits are independent from `code_read` result limits. Positions are checked against the exact synchronized UTF-16 line, and a supplied file is synchronized before workspace-symbol queries.
Definitions, references, symbols, and diagnostics are normalized, deduplicated, deterministically sorted, capped, and paged by both item count and rendered/structured UTF-8 bytes. Counts identify duplicates, invalid or outside-workspace entries, omitted items, source bytes, and concrete limit reasons. Diagnostics are marked fresh only when a server-supplied version corresponds to the current synchronized document version. Versionless diagnostics are never certified as fresh; they may be returned as stale evidence with incomplete coverage. Diagnostic retention is deduplicated and ordered deterministically with explicit item, byte, and serialization-loss causes.
## Security
Read [Security model](docs/SECURITY.md) and [Public contract matrix](docs/PUBLIC_CONTRACTS.md). Approval prompts are enabled by default. An operator may explicitly disable ordinary edit and process-start prompts independently; exact-version observation, atomic provider writes, absolute executable plans, bounded execution, and forced read-only process policy remain mandatory. Full confinement is the default requirement. Native Windows may accept DSH-reported partial enforcement only when `processPolicy.allowWindowsPartialReadOnlyProcessConfinement` is explicitly enabled. Sandbox escalation approval is never bypassed.
## Development
```sh
pnpm install
pnpm typecheck
pnpm test
pnpm build
pnpm pack --dry-run
```
This repository is independent from the DSH source checkout. Never patch DSH to mount it.
Install
dsh plugin --profile web add github:leonardoxr/dsh-coding-tools
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-coding-tools from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.