DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Direnv — DSH Plugin for DeepSeek Harness
← Plugins
D

dsh-direnv

Direnv

Workspace-aware direnv environment injection for DeepSeek Harness, with user-approved .envrc authorization

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:snylonue/dsh-direnv#745e33b4793de9e491bd0423782671867088aaef
READMECompatibilityVersions

Compatibility and provenance

Direnv is published as dsh-direnv and currently resolves to version 0.1.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
9/25/2026

Versions

0.1.0stable
9/25/2026

Related plugins

Loading related plugins…

Latest
0.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
9/25/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in

Related plugins

More verified plugins in security-access.

Doctor@linxin666/dsh-doctorTransactional rescue mode for DSH profiles with a supervised launcher, isolated recovery capsule, deterministic repairs, health monitoring, and a local Web recovery consoleDSCODE@toddzheng024/dscode-bundleA complete DeepSeek coding agent with persistent shell, Ultra collaboration and automatic permission review.Auto Reviewdsh-auto-reviewSecond-model AI auto-review for DeepSeek Harness approval requests: a read-only reviewer subagent decides allow/deny on the approval answerer chain, with fail-closed fallback and full session-log audit.Agy Linkdsh-agy-linkGoogle Antigravity (agy CLI) models for DeepSeek Harness — stream Gemini/Claude/GPT-OSS subscriptions into DSH with thinking, tool activity, token usage and in-GUI Google OAuth login.

README

dsh-direnv

Workspace-aware direnv support for DeepSeek Harness: every agent-owned shell command automatically receives its workspace's .envrc environment, and a blocked .envrc produces an actionable notice plus a direnv_allow tool that asks the user before authorizing anything.

What it does

Injectsthe environment direnv export json reports for the command's directory, merged into the child's environment map
Per workspacethe workspace comes from the calling agent's session cwd; the command's own workdir selects a nested .envrc, like native direnv
Never wraps commandsrequest.command is byte-identical to what the model asked for — injection is an environment map, so a workspace cannot inject shell syntax
Asks before allowingdirenv_allow routes through DSH's approval channel; the user sees the path, its SHA-256, and a bounded preview
Fails closeda blocked, denied, or changed .envrc injects nothing and says so; no approval service means no approval

The blocked-workspace UX

An unapproved .envrc does not fail the command and does not leak its contents. The command runs without the environment, and the result's stderr gains a notice the model can act on:

[dsh-direnv] This command ran WITHOUT the workspace direnv environment.
[dsh-direnv] /home/me/proj/.envrc is not approved, so native direnv refused to load it.
[dsh-direnv] Call the direnv_allow tool with this path to ask the user to approve it:
[dsh-direnv]   direnv_allow path=/home/me/proj/.envrc
[dsh-direnv] Workspace: /home/me/proj

The model then calls direnv_allow. The user is shown the path, the file size, its SHA-256, and a bounded preview of the contents, and must approve. Only allowed-once proceeds; rejection, cancellation, and an unreachable answerer all refuse, and the file is written by the host's own direnv allow.

Approval authorizes exactly the current content: editing the .envrc afterwards invalidates it in direnv's own hash, and the next command is blocked again until it is re-approved.

A denied .envrc is reported distinctly, because direnv ≥ 2.33 makes direnv deny revoke authorization silently — direnv export still exits zero, applying nothing. Simply seeing an empty result cannot tell that apart from a legitimately empty file, so the plugin consults direnv's own deny store (whose file name is direnv's pathHash, reproducing it exactly). A denied file gets its own notice pointing at direnv status; an empty one is treated as "nothing to inject" and stays quiet.

Caching and manual reload

Each directory is resolved once and the answer is reused, so a workspace pays for one direnv export rather than one per command. The cache is keyed by the directory that selects the .envrc, and its validity is a cheap stamp over everything that can change the answer:

  • the governing .envrc — its size and mtime (an edit also invalidates direnv's own content hash);
  • direnv's allow and deny stores — so a direnv allow or direnv deny run in your own terminal is observed, even though it changes no file the plugin could otherwise see.

When that is not enough — a dependency of the .envrc you changed, an environment direnv reads that this plugin cannot observe — call the direnv_reload tool:

direnv_reload                          # re-resolve the calling workspace
direnv_reload directory=/path/to/ws    # re-resolve one directory
direnv_reload                          # with nothing cached: resolves nothing, says so

It reports each directory's resulting state and which variable names were added or removed. It only reads: it never approves a file and needs no user approval.

Configuration

- id: direnv
  name: dsh-direnv
  config:
    executable: direnv          # bare PATH name or absolute path
    enabled: true               # master switch
    probeTimeoutMs: 10000       # budget for one direnv run
    notifyOnBlocked: true       # append the actionable notice to results
    restrictAllowToWorkspace: true  # direnv_allow may only name a file inside the agent's workspace
    followWorkdir: true         # the command's own directory selects the .envrc
    cache: true                 # resolve each directory once; reload on demand
    previewBytes: 2048          # bounded preview shown in the approval prompt
FieldDefaultMeaning
executabledirenvThe direnv binary; must be on PATH or absolute.
enabledtrueWhen off, the adapter is inert and no probe runs.
probeTimeoutMs10000One direnv export json run is killed past this.
notifyOnBlockedtrueOff keeps results byte-identical to an un-instrumented run.
restrictAllowToWorkspacetrueOn, direnv_allow refuses any path outside the agent's workspace, including via .. or a symlink.
followWorkdirtrueOn, a command run in <ws>/packages/api picks up that .envrc. Off, every command uses the session workspace root.
cachetrueResolve each directory once and reuse the result. The cache refreshes itself when the .envrc changes or when direnv's allow/deny store is rewritten, and direnv_reload forces a refresh. Off, every command pays the probe (about 35 ms for an allowed .envrc).
previewBytes2048How much of the .envrc the user sees. 0 shows only the hash.

Installation

From GitHub

dsh plugin --profile web add github:snylonue/dsh-direnv

# If failed, allow the git repo to run its prepare script, then re-run step 1.
cat >> ~/.dsh/profiles/web/pnpm-workspace.yaml <<'EOF'
allowBuilds:
  'dsh-direnv@git+https://github.com/snylonue/dsh-direnv.git': true
EOF

From a local path or tarball

dsh plugin --profile web add /path/to/dsh-direnv        # link:, requires dist/ to exist
dsh plugin --profile web add /path/to/dsh-direnv.tgz    # packed, self-contained
dsh --profile web --dump-config                         # confirm the three rows

The plugin only takes effect after a restart. DSH composes the plugin tree at boot, so an already-running host does not pick up newly installed rows; the settings-page plugin list reflects the live loader and will not show it until then either.

To uninstall, use dsh plugin --profile web remove dsh-direnv.

Requirements and limits

  • The shell service must exist. The provider injects into ctx.shell's calls; without a shell there is nothing to inject, so activation fails loudly.
  • Approval is required for direnv_allow. With no approval channel composed, the tool refuses rather than approving on its own.
  • direnv deny semantics are direnv's. On direnv >= 2.33 a denied .envrc makes direnv export succeed while applying nothing; this plugin reports that case as denied and tells the user to check with direnv status.
  • Persistent terminals are out of scope. DSH mounts terminals inside a preset-private realm; this plugin covers the bash tool (ctx.shell).
  • direnv export json returns a diff against the environment direnv ran in. The plugin filters it: DSH_* and DIRENV_* names are dropped, as is any name that is not a portable environment identifier.
  • unset compiles to removal, not absence. An environment map cannot remove a variable by omitting it — the executor merges the map onto the credential-scrubbed parent environment, so an absent name keeps the inherited value. A .envrc's unset FOO therefore becomes an undefined value, which is the subprocess seam's removal convention, and the child genuinely does not have FOO. The renderer types the map as Record<string, string>, so the widening is narrowed again at that one boundary.

Development

pnpm install
pnpm typecheck   # source AND tests
pnpm test        # builds, then runs vitest

The suite (119 tests) runs in layers:

  • pure core logic — RC discovery, diff parsing, filtering, refusals, the cache stamp, and the deny-store hash the plugin reproduces from direnv;
  • the method chain, including the non-LIFO disposal case a naive descriptor-restoring wrapper gets wrong;
  • the approval gate, asserting that nothing reaches direnv allow without an explicit allowed-once;
  • end-to-end runs against the real direnv binary;
  • real compositions that boot dsh-subprocess-local + dsh-bash-local + dsh-shell-env + dsh-tool-bash, drive the model-facing bash, direnv_allow, and direnv_reload tools through the actual tool registry, and assert on what a genuine child process received.

Tests never touch the developer's real direnv authorization store: every workspace, HOME, and XDG root lives in one temp tree.

License

MIT.