dsh-win-tools
v0.1.0
Published
Eight read-only Windows diagnostics for DSH agents: explain a path's spelling and defects, find the process holding a file, resolve which process owns a port, inspect service state and dependencies, list processes and services, trace an environment variab
Maintainers
Readme
dsh-win-tools
Eight read-only Windows diagnostics for DSH (DeepSeek Harness) agents — the questions that otherwise send you to Resource Monitor, Process Explorer or services.msc by hand.
Everything here answers a question and stops. No tool writes, starts, stops, kills, deletes or downloads anything. That is the point: a lookup should never be a side effect.
Install
dsh plugin add dsh-win-toolsOr from a local checkout:
dsh plugin add "file:/path/to/dsh-win-tools"Requires Windows and PowerShell (present on every supported Windows version).
The eight tools
win_path_resolve — why does this path not work?
Reports a path in all four dialects that coexist on Windows (C:\..., C:/..., Git-Bash /c/..., extended \\?\...) and the defects that silently break tooling:
| Detected | Why it matters |
|---|---|
| Path ≥ 260 chars | Legacy MAX_PATH; tools built without long-path support just fail |
| Segment > 255 chars | Filesystem limit; cannot exist even with \\?\ |
| Reserved names (CON, NUL, COM1…) | Cannot be created without the \\?\ prefix |
| Trailing dot or space | Windows silently strips it, resolving to a different file |
| &, \|, %, !, backtick, quotes | Shell metacharacters; quote or do not interpolate |
| MSYS /c/... form | Native programs cannot resolve it |
{
"input": "/c/Program Files/app",
"windowsPath": "C:\\Program Files\\app",
"msysPath": "/c/Program Files/app",
"extendedPath": "\\\\?\\C:\\Program Files\\app",
"issues": [{ "kind": "msys-style", "severity": "low", "detail": "…" }]
}win_file_lock — who is holding this file?
Answers EBUSY, EPERM, and "The process cannot access the file because it is being used by another process" with the actual culprit. Uses Sysinternals handle.exe when it is on PATH (the authoritative answer for data handles), and otherwise reports processes that mapped the file as a loaded module — which is what blocks most rebuilds and reinstalls.
win_process_find — what is on port 3000?
Give a port to get the owning process and its endpoints; give a process name to get every endpoint it holds.
port 445 → pid 4 (System), listening on :::445win_service_status — full state of one service
Status, start mode, image path, the account it runs under, what it dependsOn, what requiredBy, and whether it can be stopped or paused.
win_service_list — find services
Filter by a name fragment (matched against both service name and display name) and/or by state. Useful for "is anything running that should not be".
win_process_list — what is eating memory
Processes with pid, working-set memory, executable path and start time, sorted by memory descending. Filter by exact name or pid.
win_env_inspect — why is the variable not taking effect?
Returns a variable's value from each scope separately (Process / User / Machine) plus the effective value. "Works in my terminal but not in the app" is nearly always a scope mismatch, and this shows it directly.
For PATH it also verifies every entry and lists the dead ones:
MISSING:
C:\Users\you\binThat is the usual reason a freshly installed tool still reads as command not found.
win_disk_usage — what is eating the disk?
Total size, file and directory counts, and the immediate children ranked by bytes so the offender is obvious.
Two deliberate choices:
- Junctions and symlinks are not followed. Following them is how a size scan ends up reporting the entire drive under
C:\Windows. - Hard links are counted once, keyed by device + inode.
Design notes
Injection safety. Every user-supplied value reaches PowerShell as a -EncodedCommand parameter or as a single-quote-escaped literal — never spliced raw into script text. Paths, process names and service names are all untrusted input, and this plugin treats them that way.
No hangs. Each invocation has a hard timeout and the child process is killed on expiry, so a wedged cmdlet cannot freeze the agent.
Structured output. All PowerShell results are JSON, so callers get data rather than text to scrape with regexes.
Read-only by design. No tool performs destructive or state-changing operations. When something needs to be stopped or killed, the plugin reports the finding and leaves the decision — and the command — to you.
Licence
MIT
