dsh-web-search-ddg
aooyoo
Zero-token DuckDuckGo search provider for the DeepSeek Harness (DSH) web seam — local headless browser, no API key, no m…
PROJECT TOPICS
PROJECT README
English | 中文
Workspace-scoped Python virtual environment management for a DeepSeek Harness project — discover, create, install into, and remove virtual environments without sandbox, network, or subprocess pitfalls.
A DeepSeek Harness plugin that gives one project (workspace) agent-facing Python virtual environment management:
pyenv_discover, pyenv_create, pyenv_install, pyenv_uninstall, pyenv_remove — plus the python-env skill and a system-prompt guidance section.python -m venv / pip through the platform subprocess channel (host process) instead of the sandboxed shell, so venv creation, ensurepip bootstrapping, and package-index network access work where shell-side pip fails.index / proxy arguments pin either.<workspace>/.dsh-pyenv/; commands are argv arrays (no shell); the global Python environment, host pip cache, and system temp are never touched.Scripts vs bin, py -3 vs python3).ensurepip.@deepseek-ai/dsh-base (it provides the subprocess, jobs, tools, and skills services the plugin uses)From npm:
dsh plugin --profile web add dsh-python-env
From a local checkout (development):
dsh plugin --profile web add link:<absolute-path-to-this-repo>
Then restart the DSH backend — the host composition loads at process start. The tools appear in new sessions: pyenv_discover, pyenv_create, pyenv_install, pyenv_uninstall, pyenv_remove, plus the python-env skill.
Agent side:
| Tool | What it does |
|---|---|
pyenv_discover |
Find environments up to two levels deep by the pyvenv.cfg marker or conventional names (.venv, venv, env, .env, virtualenv); report path, interpreter, version, pip availability. |
pyenv_create |
Create an environment with python -m venv — name / root_dir / base python arguments, idempotent on existing environments. |
pyenv_install |
Install packages and/or a requirements file into an environment (explicit venv / discovered / auto-created .venv); repairs missing pip via ensurepip; mirror/proxy fallback; upgrade flag; editable installs of local projects; run_in_background for long installs. |
pyenv_uninstall |
Remove packages from an environment (pip uninstall -y); offline; never auto-creates an environment. |
pyenv_remove |
Delete a real workspace environment only (refuses non-environments and workspace escapes). |
pyenv_create # -> .venv, interpreter path reported
pyenv_install { packages: ["pytest>=8"] } # installs into .venv
pyenv_install { requirements: "requirements.txt" }
pyenv_uninstall { packages: ["pytest"] } # removes packages again
pyenv_discover # inspect every environment
# run code with the reported interpreter:
# Windows: <venv>\Scripts\python.exe macOS/Linux: <venv>/bin/python
Behavior notes:
"pkg==1.2.3"), upgrade (upgrade: true), install from requirements.txt (requirements), and editable installs of local projects (packages: ["-e", "."] — the editable path must stay inside the workspace; remote/VCS editable URLs are rejected).venv argument, pyenv_install uses the single discovered environment (preferring .venv), auto-creates .venv when none exists, and asks for an explicit venv when several exist.job_output, stop with job_kill.[Errno 13] during ensurepip/wheel unpacking) and package-index network access. Plugin code runs in the host process, so every python/pip/venv invocation goes through ctx.subprocess (the same channel the graphlint plugin uses) with argv arrays, byte-capped collected output, and tree-scoped termination. The unrestricted token is compensated by the confinement model below — not by weakening the sandbox.guardWorkspacePath (absolute resolution + containment, ..-safe); venv names are single-segment regex-validated and re-guarded after join; children get PIP_CACHE_DIR / TMP / TEMP / TMPDIR re-pointed into <workspace>/.dsh-pyenv/.<venv-python> -m ensurepip --upgrade bootstraps pip offline from bundled wheels; when ensurepip itself is absent the error carries the Debian/Ubuntu python3-venv hint.isConcurrencySafe: false, so the scheduler serializes them; discovery stays read-only.python-env skill teaches tool-first usage and the "never escalate for pip" rule; one system-prompt section (dsh-python-env:guidance, order 120) reminds every session that the pyenv tools are the sanctioned path.| Path | Purpose |
|---|---|
cordis.patch.yml |
Profile patch layer inserting the dsh-python-env row |
lib/index.js |
Host plugin: registers the five tools, the skill, and the guidance section |
lib/tools/ |
The five model tools (discover / create / install / uninstall / remove) |
lib/guard.js, lib/venv.js, lib/layout.js, lib/paths.js, lib/python.js |
Workspace confinement, venv resolution, discovery, platform layouts, interpreter chains |
lib/runner.js, lib/pip.js, lib/envdir.js |
Subprocess seam, install chain, workspace caches |
test/ |
Runtime-free behavior tests (see Development) |
docs/ |
Design and analysis documents |
No build step: the plugin is plain ESM and the tests run with Node directly
(the mock ctx stands in for the DSH services; the real defineTool validates
every schema):
npm test
# or: node --test --test-isolation=none "test/*.test.js"
See CONTRIBUTING.md for the development loop, including offline dependency resolution.
dsh-multi-folder (optional, zero dependency) — when the dsh-multi-folder plugin is also installed, its configured secondary working directories automatically become valid roots for every pyenv_* tool: environments there can be discovered, created, installed into, uninstalled from, and removed under the same session mode multi-folder's interception grants (workspace-write sessions can write, read-only sessions are still refused by the policy gate). The integration is a silent capability probe — without multi-folder nothing changes: no extra context, no dependency, no user-visible difference.
Installing packages means executing third-party code: pyenv_install (including the auto-created .venv path) downloads and runs code from the configured index with the host user's privileges, and editable installs import in-workspace projects as-is. The plugin mitigates this with HTTPS-only indexes, workspace-only blast radius (a compromised environment is disposable via pyenv_remove), full routing transparency, session policy parity (read-only sessions cannot trigger any of it), and per-profile opt-in. See SECURITY.md for the complete threat model and mitigation list.
See CONTRIBUTING.md. Issues and pull requests are welcome.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。