前言¶
在 DeepSeek Harness(DSH)裏,Agent 通過 bash 工具改代碼、跑構建。若項目用 Nix flake 定義 devShell,工具鏈和依賴都在 /nix/store 裏;而 Harness 默認在宿主 shell 裏執行命令,容易出現「本機沒裝 dune / ocaml」「PATH 不對」這類問題。手工每條命令前加 nix develop --command 不現實,模型也未必知道當前該不該用 Nix 環境。
下面介紹社區插件 dsh-nix-dev-shell(維護者 running-grass,分類:工作流):當命令工作目錄或其上級目錄存在 flake.nix 時,自動把 bash 放進該 flake 的 devShell,且不替換 DSH 自帶的 shell 執行器,沙箱、超時、後臺任務等行爲保持不變。
這是什麼¶
dsh-nix-dev-shell 是 Host 側 JS 插件(MIT,當前 package 版本 0.3.0,需 Node ≥ 20)。它修飾 Harness 的 ctx.shell.execute,在 dsh-bash-* 執行器之上做一層裝飾,而不是換掉執行器本身。
定位一句話:工作區有 flake 時,讓 DSH 的 bash 命令等價於在 nix develop 環境裏跑;沒有 flake、沒有 nix、或捕獲失敗時,原樣退回原生 bash 並打日誌告警。
- 目錄頁:https://www.skillhub.cn/plugins/running-grass/dsh-nix-dev-shell
- 源碼:https://github.com/running-grass/dsh-nix-dev-shell
核心功能¶
祖先目錄查找 flake¶
按 spec.workdir 向上查找 flake.nix(默認文件名可配置,最多向上 40 層),行爲類似 direnv 的祖先查找。命中後對該 flake 目錄的 devShell 生效;未命中則不注入任何東西。
兩種運行模式¶
env(默認):對 flake 目錄一次性運行nix print-dev-env(含 shellHook),與當前進程環境做差集後緩存,注入到每次 spawn 進程的env。後續每條命令沒有 nix 啓動開銷,shellHook 的標準輸出也不會混進工具結果。wrap:把命令改寫成nix develop <flakeDir> --command bash -c '…',語義與手工nix develop一致,但每條命令多一次 nix 求值(README 稱約 0.3–1s),且 shellHook 輸出會出現在結果裏。
與 Harness 其它能力的關係¶
因爲始終調用原執行器,以下不受影響:文件沙箱(workspace-write / read-only / danger-full-access)與提權審批;超時、onExpiry、abort、輸出截斷;後臺任務與 run_in_background;DSH_* 等受管環境變量(由 ctx.shellEnv 收集,優先級最高)。捕獲 devShell 時通過未修飾的原執行器跑 helper,沙箱策略與調用方相同,不會額外提權。
沙箱內的 Nix 緩存¶
workspace-write 沙箱下 ~/.cache 只讀,直接跑 nix develop 等會報 fetcher cache 無法打開。插件在 flake 工作區內、且命令受沙箱約束時,可注入 NIX_CACHE_HOME(默認相對 flake 根爲 .dsh-plugins/.cache/nix),隻影響 nix,不整體改 XDG_CACHE_HOME。danger-full-access 下不自動注入。
告訴模型「已在 devShell 裏」¶
可選地向系統提示詞貢獻一句正面陳述(promptContext,默認開啓):說明 bash 在指定 flake 的 nix develop 環境裏,IN_NIX_SHELL=impure、工具來自 /nix/store。僅在已成功捕獲 devShell 且 cwd 在 flake 子樹內纔出現;agent/created 時可預捕獲(最多約 2.5s),便於首條系統提示詞即準確。
緩存與失效¶
每個 flake 目錄的戳記由 flake.nix、flake.lock 及目錄三層內 *.nix(有界掃描)的 mtime/size 組成;捕獲失敗在 retryMs 內負緩存。刷新失敗時優先複用上次成功捕獲的環境,從未成功過纔回退原生 shell。
安裝與啓用¶
官方安裝命令(來自 README):
dsh plugin --profile web add github:running-grass/dsh-nix-dev-shell
Host 插件是 JS 模塊,安裝或更新後需要重啓 DSH 進程纔會加載新代碼。
開發時也可在會話裏通過 plugin_manager 從本地目錄安裝:
{ "action": "install_bundle", "target": "/abs/path/to/dsh-nix-dev-shell" }
安裝後執行 plugin_manager list_plugins,應看到 include:nix-dev-shell 且 fiberPhase=active。
驗證與典型用法¶
裝好後,在含 flake.nix 的目錄或其子目錄執行:
echo $IN_NIX_SHELL # impure
command -v ocaml dune # /nix/store/…(宿主機上沒有它們)
echo $NIX_CACHE_HOME # 沙箱可寫的 nix 緩存目錄
在不含 flake 的目錄(例如 $HOME)應保持原生環境,插件不會注入。
常用配置項在 cordis.patch.yml 中已有默認值,可在行內 config 調整,例如:
| 鍵 | 默認 | 說明 |
|---|---|---|
enabled |
true |
總開關 |
mode |
'env' |
'env' 注入環境 / 'wrap' 走 nix develop --command |
flakeFile |
'flake.nix' |
向上查找的文件名 |
maxAncestors |
40 |
最多向上查找層數 |
injectCacheHome |
true |
沙箱內是否注入 NIX_CACHE_HOME |
promptContext |
true |
是否向系統提示詞說明 devShell 已生效 |
prefetch |
true |
agent/created 時預捕獲 devShell |
完整表格與 captureTimeoutMs、ttlMs、cacheDir、nixCommand 等見倉庫 README。
卸載示例:
{ "action": "remove_bundle", "target": "dsh-nix-dev-shell" }
適用場景與注意¶
適合誰:用 Nix flake 管理 devShell 的倉庫,在 DSH 裏希望 Agent 的 bash 自動帶上 flake 裏的編譯器、包管理器和 shellHook 導出的變量,又不想改每條命令或換執行器。
安全與邊界:
- 祖先查找意味着:若
$HOME或上層目錄有flake.nix,其子樹內每條 bash 都會進該 devShell,第三方倉庫首次命令也會跑其shellHook。只在可信倉庫啓用,或設enabled: false、調小maxAncestors。 - 只覆蓋
ctx.shell(bash 工具、子代理、hooks、後臺任務);PTY / tmux 不在範圍內。 env模式不傳 shell 函數、別名;與「替換ctx.shell服務」的插件不兼容。- 插件以當前 DSH 進程權限運行;安裝前請閱讀源碼與 MIT 許可證,自行評估是否納入工作流。
DSH 生態是「一切皆插件」;SkillHub 等社區目錄爲獨立站點,與 DeepSeek / 幻方無官方從屬關係。
結尾¶
dsh-nix-dev-shell 把「工作區有 flake 就用 devShell」做成透明裝飾層:默認 env 模式低開銷注入,沙箱下配合 NIX_CACHE_HOME,並可選告知模型當前環境。需要完整配置、性能實測與安全說明時,以 GitHub README 爲準。